diff --git a/.env b/.env index 6a5cc6e..f13e629 100644 --- a/.env +++ b/.env @@ -1,3 +1,2 @@ MONGOURI=mongodb://jheuel:bla@localhost/?retryWrites=true&w=majority -API_ROOT=http://localhost:8080 SECRET=mila-likes-the-ol-moonwalk-and-that-is-how-she-rolls-bla-bla-bla diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..f1c96fe --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,16 @@ +{ + "cSpell.words": [ + "actix", + "bindgen", + "creds", + "dotenv", + "Gloo", + "minio", + "noopener", + "noreferrer", + "onclick", + "ondragover", + "ondrop", + "onresize" + ] +} diff --git a/Cargo.lock b/Cargo.lock index aa2c619..6347176 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -68,7 +68,7 @@ dependencies = [ "actix-service", "actix-utils", "ahash", - "base64", + "base64 0.13.0", "bitflags", "brotli", "bytes", @@ -562,6 +562,22 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "debc29dde2e69f9e47506b525f639ed42300fc014a3e007832592448fa8e4599" +[[package]] +name = "attohttpc" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "262c3f7f5d61249d8c00e5546e2685cd15ebeeb1bc0f3cc5449350a1cb07319e" +dependencies = [ + "http", + "log", + "native-tls", + "openssl", + "serde", + "serde_json", + "url", + "wildmatch", +] + [[package]] name = "atty" version = "0.2.14" @@ -579,6 +595,31 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "aws-creds" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aeeee1a5defa63cba39097a510dfe63ef53658fc8995202a610f6a8a4d03639" +dependencies = [ + "attohttpc", + "dirs", + "rust-ini", + "serde", + "serde-xml-rs", + "thiserror", + "time 0.3.10", + "url", +] + +[[package]] +name = "aws-region" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f92a8af5850d0ea0916ca3e015ab86951ded0bf4b70fd27896e81ae1dfb0af37" +dependencies = [ + "thiserror", +] + [[package]] name = "backend" version = "0.1.0" @@ -593,6 +634,7 @@ dependencies = [ "env_logger", "log", "mongodb", + "rust-s3", "serde", "serde_json", "uuid 1.3.0", @@ -605,6 +647,12 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +[[package]] +name = "base64" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" + [[package]] name = "bincode" version = "1.3.3" @@ -677,7 +725,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8746d07211bb12a7c34d995539b4a2acd4e0b0e757de98ce2ab99bcf17443fad" dependencies = [ "ahash", - "base64", + "base64 0.13.0", "hex", "indexmap", "lazy_static", @@ -823,7 +871,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94d4706de1b0fa5b132270cddffa8585166037822e260a944fe161acd137ca05" dependencies = [ "aes-gcm", - "base64", + "base64 0.13.0", "hkdf", "hmac", "percent-encoding", @@ -834,6 +882,16 @@ dependencies = [ "version_check", ] +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.3" @@ -1038,6 +1096,32 @@ dependencies = [ "subtle", ] +[[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dlv-list" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257" + [[package]] name = "dotenv" version = "0.15.0" @@ -1107,6 +1191,27 @@ dependencies = [ "termcolor", ] +[[package]] +name = "errno" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +dependencies = [ + "errno-dragonfly", + "libc", + "winapi", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "event-listener" version = "2.5.3" @@ -1150,6 +1255,21 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.0.1" @@ -1565,6 +1685,9 @@ name = "hashbrown" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3" +dependencies = [ + "ahash", +] [[package]] name = "heck" @@ -1627,6 +1750,17 @@ dependencies = [ "itoa 1.0.2", ] +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + [[package]] name = "http-range" version = "0.1.5" @@ -1651,6 +1785,43 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +[[package]] +name = "hyper" +version = "0.14.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02c929dc5c39e335a03c405292728118860721b10190d98c2a0f0efd5baafbac" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa 1.0.2", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "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]] name = "iana-time-zone" version = "0.1.53" @@ -1729,6 +1900,16 @@ dependencies = [ "num-traits", ] +[[package]] +name = "io-lifetimes" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1abeb7a0dd0f8181267ff8adc397075586500b81b28a73e8a0208b00fc170fb3" +dependencies = [ + "libc", + "windows-sys 0.45.0", +] + [[package]] name = "ipconfig" version = "0.3.1" @@ -1809,9 +1990,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.126" +version = "0.2.139" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" +checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" [[package]] name = "link-cplusplus" @@ -1828,6 +2009,12 @@ version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" +[[package]] +name = "linux-raw-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" + [[package]] name = "local-channel" version = "0.1.3" @@ -1887,6 +2074,17 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" +[[package]] +name = "maybe-async" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f1b8c13cb1f814b634a96b2c725449fe7ed464a7b8781de8688be5ffbd3f305" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "md-5" version = "0.10.5" @@ -1896,6 +2094,12 @@ dependencies = [ "digest", ] +[[package]] +name = "md5" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" + [[package]] name = "memchr" version = "2.5.0" @@ -1924,6 +2128,15 @@ dependencies = [ "unicase", ] +[[package]] +name = "minidom" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e9ce45d459e358790a285e7609ff5ae4cfab88b75f237e8838e62029dda397b" +dependencies = [ + "rxml", +] + [[package]] name = "miniz_oxide" version = "0.5.3" @@ -1954,7 +2167,7 @@ dependencies = [ "async-std", "async-std-resolver", "async-trait", - "base64", + "base64 0.13.0", "bitflags", "bson", "chrono", @@ -1992,6 +2205,24 @@ dependencies = [ "webpki-roots", ] +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "num-integer" version = "0.1.45" @@ -2042,6 +2273,61 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +[[package]] +name = "openssl" +version = "0.10.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b102428fd03bc5edf97f62620f7298614c45cedf287c271e7ed450bbaf83f2e1" +dependencies = [ + "bitflags", + "cfg-if 1.0.0", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23bbbf7854cd45b83958ebe919f0e8e516793727652e27fda10a8384cfc790b7" +dependencies = [ + "autocfg", + "cc", + "libc", + "pkg-config", + "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]] name = "os_info" version = "3.6.0" @@ -2164,6 +2450,12 @@ dependencies = [ "thiserror", ] +[[package]] +name = "pkg-config" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" + [[package]] name = "polling" version = "2.5.2" @@ -2316,6 +2608,17 @@ dependencies = [ "bitflags", ] +[[package]] +name = "redox_users" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +dependencies = [ + "getrandom", + "redox_syscall", + "thiserror", +] + [[package]] name = "regex" version = "1.5.6" @@ -2339,6 +2642,45 @@ version = "0.6.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" +[[package]] +name = "reqwest" +version = "0.11.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21eed90ec8570952d53b772ecf8f206aa1ec9a3d76b2521c56c42973f2d91ee9" +dependencies = [ + "base64 0.21.0", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-native-tls", + "tokio-util", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "winreg", +] + [[package]] name = "resolv-conf" version = "0.7.0" @@ -2370,6 +2712,47 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afab94fb28594581f62d981211a9a4d53cc8130bbcbbb89a0440d9b8e81a7746" +[[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]] +name = "rust-s3" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6009d9d4cf910505534d62d380a0aa305805a2af0b5c3ad59a3024a0715b847" +dependencies = [ + "async-trait", + "aws-creds", + "aws-region", + "base64 0.13.0", + "cfg-if 1.0.0", + "hex", + "hmac", + "http", + "log", + "maybe-async", + "md5", + "minidom", + "percent-encoding", + "reqwest", + "serde", + "serde-xml-rs", + "serde_derive", + "sha2", + "thiserror", + "time 0.3.10", + "tokio", + "tokio-stream", + "url", +] + [[package]] name = "rustc-hash" version = "1.1.0" @@ -2404,6 +2787,20 @@ dependencies = [ "semver 0.9.0", ] +[[package]] +name = "rustix" +version = "0.36.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43abb88211988493c1abb44a70efa56ff0ce98f233b7b276146f1f3f7ba9644" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.45.0", +] + [[package]] name = "rustls" version = "0.20.8" @@ -2422,7 +2819,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ee86d63972a7c661d1536fefe8c3c8407321c3df668891286de28abcd087360" dependencies = [ - "base64", + "base64 0.13.0", ] [[package]] @@ -2431,6 +2828,25 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5583e89e108996506031660fe09baa5011b9dd0341b89029313006d1fb508d70" +[[package]] +name = "rxml" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a071866b8c681dc2cfffa77184adc32b57b0caad4e620b6292609703bceb804" +dependencies = [ + "bytes", + "pin-project-lite", + "rxml_validation", + "smartstring", + "tokio", +] + +[[package]] +name = "rxml_validation" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53bc79743f9a66c2fb1f951cd83735f275d46bfe466259fbc5897bb60a0d00ee" + [[package]] name = "ryu" version = "1.0.10" @@ -2446,6 +2862,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "schannel" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" +dependencies = [ + "windows-sys 0.42.0", +] + [[package]] name = "scopeguard" version = "1.1.0" @@ -2468,6 +2893,29 @@ dependencies = [ "untrusted", ] +[[package]] +name = "security-framework" +version = "2.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "semver" version = "0.9.0" @@ -2510,6 +2958,18 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "serde-xml-rs" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65162e9059be2f6a3421ebbb4fef3e74b7d9e7c60c50a0e292c6239f19f1edfa" +dependencies = [ + "log", + "serde", + "thiserror", + "xml-rs", +] + [[package]] name = "serde_bytes" version = "0.11.9" @@ -2653,6 +3113,15 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" +[[package]] +name = "smartstring" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e714dff2b33f2321fdcd475b71cec79781a692d846f37f415fb395a1d2bcd48e" +dependencies = [ + "static_assertions", +] + [[package]] name = "socket2" version = "0.4.4" @@ -2669,6 +3138,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "stringprep" version = "0.1.2" @@ -2708,6 +3183,19 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" +[[package]] +name = "tempfile" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af18f7ae1acd354b992402e9ec5864359d693cd8a79dcbef59f76891701c1e95" +dependencies = [ + "cfg-if 1.0.0", + "fastrand", + "redox_syscall", + "rustix", + "windows-sys 0.42.0", +] + [[package]] name = "termcolor" version = "1.1.3" @@ -2757,6 +3245,7 @@ dependencies = [ "itoa 1.0.2", "libc", "num_threads", + "serde", "time-macros", ] @@ -2812,6 +3301,16 @@ dependencies = [ "syn", ] +[[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]] name = "tokio-rustls" version = "0.23.4" @@ -2849,6 +3348,12 @@ dependencies = [ "tracing", ] +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + [[package]] name = "tracing" version = "0.1.37" @@ -2927,6 +3432,12 @@ dependencies = [ "trust-dns-proto", ] +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + [[package]] name = "typed-builder" version = "0.10.0" @@ -3037,6 +3548,12 @@ dependencies = [ "version_check", ] +[[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" @@ -3060,6 +3577,16 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "want" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +dependencies = [ + "log", + "try-lock", +] + [[package]] name = "wasi" version = "0.10.0+wasi-snapshot-preview1" @@ -3140,6 +3667,19 @@ version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" +[[package]] +name = "wasm-streams" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bbae3363c08332cadccd13b67db371814cd214c2524020932f0804b8cf7c078" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "web-sys" version = "0.3.61" @@ -3218,6 +3758,12 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17882f045410753661207383517a6f62ec3dbeb6a4ed2acce01f0728238d1983" +[[package]] +name = "wildmatch" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee583bdc5ff1cf9db20e9db5bb3ff4c3089a8f6b8b31aff265c9aba85812db86" + [[package]] name = "winapi" version = "0.3.9" @@ -3277,6 +3823,30 @@ dependencies = [ "windows_x86_64_msvc 0.42.1", ] +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.42.1", + "windows_i686_gnu 0.42.1", + "windows_i686_msvc 0.42.1", + "windows_x86_64_gnu 0.42.1", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.42.1", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.1" @@ -3358,6 +3928,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "xml-rs" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3" + [[package]] name = "ybc" version = "0.4.0-alpha.0" diff --git a/backend/Cargo.toml b/backend/Cargo.toml index 30e9040..e91906f 100644 --- a/backend/Cargo.toml +++ b/backend/Cargo.toml @@ -21,6 +21,7 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" common = { path = "../common" } uuid = { version = "1", features = ["v4", "serde"] } +rust-s3 = "0.32.3" [dependencies.mongodb] version = "2.2.0" diff --git a/backend/src/api/mod.rs b/backend/src/api/mod.rs index 9ad970a..9f32237 100644 --- a/backend/src/api/mod.rs +++ b/backend/src/api/mod.rs @@ -1 +1,2 @@ +pub mod photos_api; pub mod user_api; diff --git a/backend/src/api/photos_api.rs b/backend/src/api/photos_api.rs new file mode 100644 index 0000000..7d46df7 --- /dev/null +++ b/backend/src/api/photos_api.rs @@ -0,0 +1,57 @@ +use actix_session::Session; +use actix_web::{ + post, + web::{Data, Json}, + HttpResponse, +}; +use s3::bucket::Bucket; +use serde::{Deserialize, Serialize}; + +use crate::repository::mongodb_repo::MongoRepo; + +#[derive(Debug, Deserialize, Serialize)] +pub struct PhotosWrapper { + photos: Vec, +} + +#[derive(Debug, Deserialize, Serialize)] +pub struct PhotosUrlsWrapper { + photos: Vec<(String, String)>, +} + +// Return an opaque 500 while preserving the error's root cause for logging. +fn e500(e: T) -> actix_web::Error +where + T: std::fmt::Debug + std::fmt::Display + 'static, +{ + actix_web::error::ErrorInternalServerError(e) +} + +#[post("/api/photos/upload")] +pub async fn get_presigned_post_urls( + db: Data, + bucket: Data, + request: Json, + session: Session, +) -> Result { + let Some(user_id) = session.get::("user_id").map_err(e500)? else { + return Ok(HttpResponse::Unauthorized().body("Not authorized")); + }; + + let Ok(_) = db.get_user(&user_id).await else { + return Ok(HttpResponse::Unauthorized().body("Not authorized")); + }; + + let photos: Vec<(String, String)> = request + .photos + .iter() + .map(|x| { + ( + x.clone(), + bucket.presign_put(format!("/{x}"), 86400, None).unwrap(), + ) + }) + .collect(); + + Ok(HttpResponse::Ok().json(PhotosUrlsWrapper { photos })) +} diff --git a/backend/src/main.rs b/backend/src/main.rs index cfb4758..a95f135 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -2,10 +2,15 @@ mod api; mod models; mod repository; +use api::photos_api::get_presigned_post_urls; use api::user_api::{create_user, delete_user, get_user, is_logged_in, login, update_user}; use common::OutputPicture; use repository::mongodb_repo::MongoRepo; +use s3::bucket::Bucket; +use s3::creds::Credentials; +use s3::region::Region; + use actix_cors::Cors; use actix_session::{ config::CookieContentSecurity, storage::CookieSessionStore, SessionMiddleware, @@ -63,19 +68,44 @@ async fn main() -> std::io::Result<()> { log::info!("starting HTTP server at http://{}:{}", host, port); let db = MongoRepo::init().await; - let db_data = Data::new(db); + let db = Data::new(db); + + let bucket_name = "photos"; + let region = Region::Custom { + region: "minio".parse().unwrap(), + endpoint: "http://127.0.0.1:9000".to_owned(), + }; + let credentials = Credentials { + access_key: Some("OPyibtgH1RISFIPs".to_owned()), + secret_key: Some("LesNB0p5oZEcJy3rACHEloityS1Y6nYc".to_owned()), + security_token: None, + session_token: None, + expiration: None, + }; + let bucket = if let Ok(mut bucket) = Bucket::new(bucket_name, region, credentials) { + bucket.set_path_style(); + bucket + } else { + panic!("Could not create bucket"); + }; + let bucket = Data::new(bucket); HttpServer::new(move || { let cors = Cors::default() - .allowed_origin("http://localhost:8080") - .allowed_origin_fn(|origin, _req_head| origin.as_bytes().starts_with(b"localhost")) + .allowed_origin_fn(|origin, _req_head| { + origin + .as_bytes() + .windows("localhost".len()) + .filter(|&x| x == "localhost".as_bytes()) + .count() + > 0 + }) .allowed_methods(vec!["GET", "POST"]) .allowed_headers(vec![http::header::AUTHORIZATION, http::header::ACCEPT]) .allowed_header(http::header::CONTENT_TYPE) .max_age(3600); App::new() - // .app_data(web::Data::new(pool.clone())) .wrap(cors) .wrap( SessionMiddleware::builder( @@ -85,10 +115,11 @@ async fn main() -> std::io::Result<()> { .cookie_content_security(CookieContentSecurity::Private) .build(), ) - .app_data(db_data.clone()) + .app_data(db.clone()) + .app_data(bucket.clone()) .wrap(middleware::Logger::default()) + .service(get_presigned_post_urls) .service(get_pictures) - // .service(fs::Files::new("/api/pictures/", "./pictures/")) .service(is_logged_in) .service(login) .service(create_user) diff --git a/docker-compose.yml b/docker-compose.yml index 554918c..47d35cd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -50,3 +50,21 @@ services: ME_CONFIG_MONGODB_ADMINUSERNAME: jheuel ME_CONFIG_MONGODB_ADMINPASSWORD: bla ME_CONFIG_MONGODB_URL: mongodb://jheuel:bla@mongo:27017/ + + minio: + image: quay.io/minio/minio + command: server /data --console-address ":9001" + ports: + - 9000:9000 + - 9001:9001 + environment: + MINIO_ROOT_USER: miliminioadmin + MINIO_ROOT_PASSWORD: miliminioadmin + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"] + interval: 30s + timeout: 20s + retries: 3 + hostname: minio + volumes: + - ./s3_data:/data diff --git a/frontend/src/components/home.rs b/frontend/src/components/home.rs index 0767501..3c330e4 100644 --- a/frontend/src/components/home.rs +++ b/frontend/src/components/home.rs @@ -4,6 +4,7 @@ use crate::hooks::use_user_context; use gloo_net::http::Request; use js_sys::Array; +use serde::{Deserialize, Serialize}; use wasm_bindgen::{prelude::wasm_bindgen, JsCast, JsValue}; use web_sys::{DataTransferItemList, File, FileSystemDirectoryEntry, FileSystemEntry}; use weblog::console_log; @@ -12,6 +13,15 @@ use yew_hooks::prelude::*; use common::OutputPicture; +#[derive(Debug, Deserialize, Serialize)] +pub struct PhotosWrapper { + photos: Vec, +} +#[derive(Debug, Deserialize, Serialize)] +pub struct PhotosUrlsWrapper { + photos: Vec<(String, String)>, +} + #[function_component(Home)] pub fn home() -> Html { let user_ctx = use_user_context(); @@ -92,7 +102,7 @@ pub fn home() -> Html { let uiae: Vec = files .iter() .map(|x| { - if let Ok(filepath) = js_sys::Reflect::get(&x, &JsValue::from_str("filepath")) { + if let Ok(filepath) = js_sys::Reflect::get(x, &JsValue::from_str("filepath")) { filepath.as_string().unwrap_or("".to_string()) } else { "".to_string() @@ -100,6 +110,17 @@ pub fn home() -> Html { }) .collect(); console_log!("end", uiae.join("\n")); + let url = "/api/photos/upload"; + let photos: PhotosUrlsWrapper = Request::post(url) + .json(&PhotosWrapper { photos: uiae }) + .unwrap() + .send() + .await + .unwrap() + .json() + .await + .unwrap(); + console_log!("{}", serde_json::to_string(&photos).unwrap()); }); }); diff --git a/frontend/src/gallery/grid.rs b/frontend/src/gallery/grid.rs index 5634eaf..299bbec 100644 --- a/frontend/src/gallery/grid.rs +++ b/frontend/src/gallery/grid.rs @@ -19,6 +19,9 @@ pub fn grid(props: &GridProps) -> Html { let target_height = 100; let container_width = if props.width == 0 { 0 } else { props.width - 4 }; let margin = 2; + if container_width == 0 { + return html! {}; + } let dimensions = compute_row_layout( container_width, target_height, diff --git a/frontend/src/services/mod.rs b/frontend/src/services/mod.rs index c77484f..346bedb 100644 --- a/frontend/src/services/mod.rs +++ b/frontend/src/services/mod.rs @@ -9,7 +9,6 @@ use gloo_storage::{LocalStorage, Storage}; use lazy_static::lazy_static; use parking_lot::RwLock; -const API_ROOT: &str = dotenv!("API_ROOT"); const TOKEN_KEY: &str = "jheuel-token"; lazy_static! { diff --git a/frontend/src/services/requests.rs b/frontend/src/services/requests.rs index 345c9d1..0cd9739 100644 --- a/frontend/src/services/requests.rs +++ b/frontend/src/services/requests.rs @@ -1,4 +1,3 @@ -use super::API_ROOT; use crate::error::Error; use crate::types; use gloo_net::http::{Method, Request as GlooRequest}; @@ -7,7 +6,6 @@ use weblog::console_log; pub struct Request(Option); fn request(method: gloo_net::http::Method, url: &str, body: &B) -> Request { - let url = format!("{}{}", API_ROOT, url); let builder = GlooRequest::new(&url) .method(method) .header("Content-Type", "application/json"); @@ -56,12 +54,10 @@ impl Request { } pub fn request_delete(url: &str) -> Request { - let url = format!("{}{}", API_ROOT, url); Request(Some(GlooRequest::new(&url).method(Method::DELETE))).set_token() } pub fn request_get(url: &str) -> Request { - let url = format!("{}{}", API_ROOT, url); Request(Some(GlooRequest::new(&url).method(Method::GET))).set_token() }