From c9659f9469d443a34ab18419797878917f6d5e5a Mon Sep 17 00:00:00 2001 From: Kavika <50282464+KavikaPalletenne@users.noreply.github.com> Date: Thu, 5 Oct 2023 12:38:10 +1100 Subject: [PATCH 01/56] feat(backend): remove old backend --- backend/.dockerignore | 3 - backend/.gitignore | 3 - backend/Cargo.lock | 2873 ----------------- backend/Cargo.toml | 6 - backend/Dockerfile | 22 - .../down.sql | 6 - .../up.sql | 36 - .../2021-12-07-112918_create_users/down.sql | 1 - .../2021-12-07-112918_create_users/up.sql | 13 - .../down.sql | 1 - .../up.sql | 9 - .../down.sql | 2 - .../up.sql | 12 - .../2021-12-07-114733_campaigns/down.sql | 1 - .../2021-12-07-114733_campaigns/up.sql | 14 - .../2021-12-07-114906_roles/down.sql | 1 - .../migrations/2021-12-07-114906_roles/up.sql | 13 - .../2021-12-07-115409_questions/down.sql | 1 - .../2021-12-07-115409_questions/up.sql | 12 - .../2021-12-07-115608_applications/down.sql | 2 - .../2021-12-07-115608_applications/up.sql | 12 - .../2021-12-07-115832_answers/down.sql | 1 - .../2021-12-07-115832_answers/up.sql | 10 - .../2021-12-07-115931_comments/down.sql | 1 - .../2021-12-07-115931_comments/up.sql | 10 - .../2021-12-07-120033_ratings/down.sql | 1 - .../2021-12-07-120033_ratings/up.sql | 10 - .../2022-05-30-145617_questions/down.sql | 0 .../2022-05-30-145617_questions/up.sql | 20 - .../down.sql | 2 - .../up.sql | 9 - .../2022-12-04-065103_image_files/down.sql | 5 - .../2022-12-04-065103_image_files/up.sql | 5 - .../2023-06-07-042751_user_gender/down.sql | 4 - .../2023-06-07-042751_user_gender/up.sql | 4 - .../2023-09-20-052638_user_pronouns/down.sql | 2 - .../2023-09-20-052638_user_pronouns/up.sql | 2 - backend/scripts/become_super_user.sh | 33 - backend/scripts/seed.sh | 18 - backend/seed_data/Cargo.toml | 12 - backend/seed_data/assets/180DC.png | Bin 216499 -> 0 bytes backend/seed_data/assets/csesoc_logo.png | Bin 12285 -> 0 bytes .../assets/csesoc_peer_mentoring.jpg | Bin 143083 -> 0 bytes backend/seed_data/src/main.rs | 8 - backend/seed_data/src/seed.rs | 311 -- backend/server/src/Cargo.lock | 2078 ------------ backend/server/src/admin.rs | 41 - backend/server/src/application.rs | 292 -- backend/server/src/auth.rs | 376 --- backend/server/src/bin.rs | 170 - backend/server/src/campaigns.rs | 308 -- backend/server/src/comment.rs | 75 - backend/server/src/cors.rs | 21 - backend/server/src/database/mod.rs | 7 - backend/server/src/database/models.rs | 1425 -------- backend/server/src/database/schema.rs | 197 -- backend/server/src/diesel.toml | 5 - backend/server/src/error.rs | 16 - backend/server/src/guard/mod.rs | 88 - backend/server/src/images.rs | 86 - backend/server/src/lib.rs | 20 - backend/server/src/organisation.rs | 375 --- backend/server/src/permissions.rs | 254 -- backend/server/src/question.rs | 113 - backend/server/src/role.rs | 228 -- backend/server/src/schema.jpg | Bin 315172 -> 0 bytes backend/server/src/schema.png | Bin 598648 -> 0 bytes backend/server/src/src/database/schema.rs | 174 - backend/server/src/state/mod.rs | 66 - backend/server/src/static_resources.rs | 26 - backend/server/src/user.rs | 88 - 71 files changed, 10040 deletions(-) delete mode 100644 backend/.dockerignore delete mode 100644 backend/.gitignore delete mode 100644 backend/Cargo.lock delete mode 100644 backend/Cargo.toml delete mode 100644 backend/Dockerfile delete mode 100644 backend/migrations/00000000000000_diesel_initial_setup/down.sql delete mode 100644 backend/migrations/00000000000000_diesel_initial_setup/up.sql delete mode 100644 backend/migrations/2021-12-07-112918_create_users/down.sql delete mode 100644 backend/migrations/2021-12-07-112918_create_users/up.sql delete mode 100644 backend/migrations/2021-12-07-114233_create_organisations/down.sql delete mode 100644 backend/migrations/2021-12-07-114233_create_organisations/up.sql delete mode 100644 backend/migrations/2021-12-07-114404_create_organisation_users/down.sql delete mode 100644 backend/migrations/2021-12-07-114404_create_organisation_users/up.sql delete mode 100644 backend/migrations/2021-12-07-114733_campaigns/down.sql delete mode 100644 backend/migrations/2021-12-07-114733_campaigns/up.sql delete mode 100644 backend/migrations/2021-12-07-114906_roles/down.sql delete mode 100644 backend/migrations/2021-12-07-114906_roles/up.sql delete mode 100644 backend/migrations/2021-12-07-115409_questions/down.sql delete mode 100644 backend/migrations/2021-12-07-115409_questions/up.sql delete mode 100644 backend/migrations/2021-12-07-115608_applications/down.sql delete mode 100644 backend/migrations/2021-12-07-115608_applications/up.sql delete mode 100644 backend/migrations/2021-12-07-115832_answers/down.sql delete mode 100644 backend/migrations/2021-12-07-115832_answers/up.sql delete mode 100644 backend/migrations/2021-12-07-115931_comments/down.sql delete mode 100644 backend/migrations/2021-12-07-115931_comments/up.sql delete mode 100644 backend/migrations/2021-12-07-120033_ratings/down.sql delete mode 100644 backend/migrations/2021-12-07-120033_ratings/up.sql delete mode 100644 backend/migrations/2022-05-30-145617_questions/down.sql delete mode 100644 backend/migrations/2022-05-30-145617_questions/up.sql delete mode 100644 backend/migrations/2022-11-21-043159_application_private_statuses/down.sql delete mode 100644 backend/migrations/2022-11-21-043159_application_private_statuses/up.sql delete mode 100644 backend/migrations/2022-12-04-065103_image_files/down.sql delete mode 100644 backend/migrations/2022-12-04-065103_image_files/up.sql delete mode 100644 backend/migrations/2023-06-07-042751_user_gender/down.sql delete mode 100644 backend/migrations/2023-06-07-042751_user_gender/up.sql delete mode 100644 backend/migrations/2023-09-20-052638_user_pronouns/down.sql delete mode 100644 backend/migrations/2023-09-20-052638_user_pronouns/up.sql delete mode 100755 backend/scripts/become_super_user.sh delete mode 100755 backend/scripts/seed.sh delete mode 100644 backend/seed_data/Cargo.toml delete mode 100644 backend/seed_data/assets/180DC.png delete mode 100644 backend/seed_data/assets/csesoc_logo.png delete mode 100644 backend/seed_data/assets/csesoc_peer_mentoring.jpg delete mode 100644 backend/seed_data/src/main.rs delete mode 100644 backend/seed_data/src/seed.rs delete mode 100644 backend/server/src/Cargo.lock delete mode 100644 backend/server/src/admin.rs delete mode 100644 backend/server/src/application.rs delete mode 100644 backend/server/src/auth.rs delete mode 100644 backend/server/src/bin.rs delete mode 100644 backend/server/src/campaigns.rs delete mode 100644 backend/server/src/comment.rs delete mode 100644 backend/server/src/cors.rs delete mode 100644 backend/server/src/database/mod.rs delete mode 100644 backend/server/src/database/models.rs delete mode 100644 backend/server/src/database/schema.rs delete mode 100644 backend/server/src/diesel.toml delete mode 100644 backend/server/src/error.rs delete mode 100644 backend/server/src/guard/mod.rs delete mode 100644 backend/server/src/images.rs delete mode 100644 backend/server/src/lib.rs delete mode 100644 backend/server/src/organisation.rs delete mode 100644 backend/server/src/permissions.rs delete mode 100644 backend/server/src/question.rs delete mode 100644 backend/server/src/role.rs delete mode 100644 backend/server/src/schema.jpg delete mode 100644 backend/server/src/schema.png delete mode 100644 backend/server/src/src/database/schema.rs delete mode 100644 backend/server/src/state/mod.rs delete mode 100644 backend/server/src/static_resources.rs delete mode 100644 backend/server/src/user.rs diff --git a/backend/.dockerignore b/backend/.dockerignore deleted file mode 100644 index 84f023f1e..000000000 --- a/backend/.dockerignore +++ /dev/null @@ -1,3 +0,0 @@ -.env -target -Dockerfile* \ No newline at end of file diff --git a/backend/.gitignore b/backend/.gitignore deleted file mode 100644 index e9480c466..000000000 --- a/backend/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.env -target -images diff --git a/backend/Cargo.lock b/backend/Cargo.lock deleted file mode 100644 index 32ab2908d..000000000 --- a/backend/Cargo.lock +++ /dev/null @@ -1,2873 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "aead" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c192eb8f11fc081b0fe4259ba5af04217d4e0faddd02417310a927911abd7c8" -dependencies = [ - "crypto-common", - "generic-array", -] - -[[package]] -name = "aes" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", -] - -[[package]] -name = "aes-gcm" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e1366e0c69c9f927b1fa5ce2c7bf9eafc8f9268c0b9800729e8b267612447c" -dependencies = [ - "aead", - "aes", - "cipher", - "ctr", - "ghash", - "subtle", -] - -[[package]] -name = "aho-corasick" -version = "0.7.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" -dependencies = [ - "memchr", -] - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] -name = "async-stream" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dad5c83079eae9969be7fadefe640a1c566901f05ff91ab221de4b6f68d9507e" -dependencies = [ - "async-stream-impl", - "futures-core", -] - -[[package]] -name = "async-stream-impl" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.103", -] - -[[package]] -name = "async-trait" -version = "0.1.58" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e805d94e6b5001b651426cf4cd446b1ab5f319d27bab5c644f61de0a804360c" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.103", -] - -[[package]] -name = "atomic" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b88d82667eca772c4aa12f0f1348b3ae643424c8876448f3f7bd5787032e234c" -dependencies = [ - "autocfg", -] - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi", -] - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "base64" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" - -[[package]] -name = "base64" -version = "0.21.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" - -[[package]] -name = "binascii" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "383d29d513d8764dcdc42ea295d979eb99c3c9f00607b3692cf68a431f7dca72" - -[[package]] -name = "bit_field" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "block-buffer" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" -dependencies = [ - "generic-array", -] - -[[package]] -name = "bumpalo" -version = "3.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" - -[[package]] -name = "bytemuck" -version = "1.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f5715e491b5a1598fc2bef5a606847b5dc1d48ea625bd3c02c00de8285591da" - -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "bytes" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" - -[[package]] -name = "cc" -version = "1.0.77" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4" -dependencies = [ - "jobserver", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chrono" -version = "0.4.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" -dependencies = [ - "iana-time-zone", - "js-sys", - "num-integer", - "num-traits", - "serde", - "time 0.1.44", - "wasm-bindgen", - "winapi", -] - -[[package]] -name = "cipher" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1873270f8f7942c191139cb8a40fd228da6c3fd2fc376d7e92d47aa14aeb59e" -dependencies = [ - "crypto-common", - "inout", -] - -[[package]] -name = "codespan-reporting" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" -dependencies = [ - "termcolor", - "unicode-width", -] - -[[package]] -name = "color_quant" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" - -[[package]] -name = "cookie" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "344adc371239ef32293cb1c4fe519592fcf21206c79c02854320afcdf3ab4917" -dependencies = [ - "aes-gcm", - "base64 0.13.1", - "hkdf", - "hmac", - "percent-encoding", - "rand", - "sha2", - "subtle", - "time 0.3.17", - "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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" - -[[package]] -name = "cpufeatures" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" -dependencies = [ - "libc", -] - -[[package]] -name = "crc32fast" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f916dfc5d356b0ed9dae65f1db9fc9770aa2851d2662b988ccf4fe3516e86348" -dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils", - "memoffset", - "scopeguard", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "rand_core", - "typenum", -] - -[[package]] -name = "ctr" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" -dependencies = [ - "cipher", -] - -[[package]] -name = "cxx" -version = "1.0.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4a41a86530d0fe7f5d9ea779916b7cadd2d4f9add748b99c2c029cbbdfaf453" -dependencies = [ - "cc", - "cxxbridge-flags", - "cxxbridge-macro", - "link-cplusplus", -] - -[[package]] -name = "cxx-build" -version = "1.0.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06416d667ff3e3ad2df1cd8cd8afae5da26cf9cec4d0825040f88b5ca659a2f0" -dependencies = [ - "cc", - "codespan-reporting", - "once_cell", - "proc-macro2", - "quote", - "scratch", - "syn 1.0.103", -] - -[[package]] -name = "cxxbridge-flags" -version = "1.0.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "820a9a2af1669deeef27cb271f476ffd196a2c4b6731336011e0ba63e2c7cf71" - -[[package]] -name = "cxxbridge-macro" -version = "1.0.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08a6e2fcc370a089ad3b4aaf54db3b1b4cee38ddabce5896b33eb693275f470" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.103", -] - -[[package]] -name = "devise" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c7580b072f1c8476148f16e0a0d5dedddab787da98d86c5082c5e9ed8ab595" -dependencies = [ - "devise_codegen", - "devise_core", -] - -[[package]] -name = "devise_codegen" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "123c73e7a6e51b05c75fe1a1b2f4e241399ea5740ed810b0e3e6cacd9db5e7b2" -dependencies = [ - "devise_core", - "quote", -] - -[[package]] -name = "devise_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841ef46f4787d9097405cac4e70fb8644fc037b526e8c14054247c0263c400d0" -dependencies = [ - "bitflags", - "proc-macro2", - "proc-macro2-diagnostics", - "quote", - "syn 1.0.103", -] - -[[package]] -name = "diesel" -version = "1.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b28135ecf6b7d446b43e27e225622a038cc4e2930a1022f51cdb97ada19b8e4d" -dependencies = [ - "bitflags", - "byteorder", - "chrono", - "diesel_derives", - "pq-sys", - "r2d2", -] - -[[package]] -name = "diesel-derive-enum" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8910921b014e2af16298f006de12aa08af894b71f0f49a486ab6d74b17bbed" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 1.0.103", -] - -[[package]] -name = "diesel_derives" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45f5098f628d02a7a0f68ddba586fb61e80edec3bdc1be3b921f4ceec60858d3" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.103", -] - -[[package]] -name = "diesel_migrations" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf3cde8413353dc7f5d72fa8ce0b99a560a359d2c5ef1e5817ca731cd9008f4c" -dependencies = [ - "migrations_internals", - "migrations_macros", -] - -[[package]] -name = "digest" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" -dependencies = [ - "block-buffer", - "crypto-common", - "subtle", -] - -[[package]] -name = "dotenv" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" - -[[package]] -name = "dotenv_codegen" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56966279c10e4f8ee8c22123a15ed74e7c8150b658b26c619c53f4a56eb4a8aa" -dependencies = [ - "dotenv_codegen_implementation", - "proc-macro-hack", -] - -[[package]] -name = "dotenv_codegen_implementation" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e737a3522cd45f6adc19b644ce43ef53e1e9045f2d2de425c1f468abd4cf33" -dependencies = [ - "dotenv", - "proc-macro-hack", - "proc-macro2", - "quote", - "syn 1.0.103", -] - -[[package]] -name = "either" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" - -[[package]] -name = "encoding_rs" -version = "0.8.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "exr" -version = "1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eb5f255b5980bb0c8cf676b675d1a99be40f316881444f44e0462eaf5df5ded" -dependencies = [ - "bit_field", - "flume", - "half", - "lebe", - "miniz_oxide 0.6.2", - "smallvec", - "threadpool", -] - -[[package]] -name = "fastrand" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" -dependencies = [ - "instant", -] - -[[package]] -name = "figment" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e56602b469b2201400dec66a66aec5a9b8761ee97cd1b8c96ab2483fcc16cc9" -dependencies = [ - "atomic", - "pear", - "serde", - "serde_json", - "toml", - "uncased", - "version_check", -] - -[[package]] -name = "flate2" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" -dependencies = [ - "crc32fast", - "miniz_oxide 0.5.4", -] - -[[package]] -name = "flume" -version = "0.10.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" -dependencies = [ - "futures-core", - "futures-sink", - "nanorand", - "pin-project", - "spin 0.9.4", -] - -[[package]] -name = "fnv" -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.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "futures" -version = "0.3.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" - -[[package]] -name = "futures-io" -version = "0.3.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" - -[[package]] -name = "futures-sink" -version = "0.3.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" - -[[package]] -name = "futures-task" -version = "0.3.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" - -[[package]] -name = "futures-util" -version = "0.3.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "generator" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc184cace1cea8335047a471cc1da80f18acf8a76f3bab2028d499e328948ec7" -dependencies = [ - "cc", - "libc", - "log", - "rustversion", - "windows", -] - -[[package]] -name = "generic-array" -version = "0.14.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", - "wasm-bindgen", -] - -[[package]] -name = "ghash" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40" -dependencies = [ - "opaque-debug", - "polyval", -] - -[[package]] -name = "gif" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3edd93c6756b4dfaf2709eafcc345ba2636565295c198a9cfbf75fa5e3e00b06" -dependencies = [ - "color_quant", - "weezl", -] - -[[package]] -name = "glob" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" - -[[package]] -name = "h2" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "half" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad6a9459c9c30b177b925162351f97e7d967c7ea8bab3b8352805327daf45554" -dependencies = [ - "crunchy", -] - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "heck" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[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 = "http" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[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 = "httparse" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" - -[[package]] -name = "httpdate" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" - -[[package]] -name = "hyper" -version = "0.14.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "winapi", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" -dependencies = [ - "cxx", - "cxx-build", -] - -[[package]] -name = "idna" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "image" -version = "0.24.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd8e4fb07cf672b1642304e731ef8a6a4c7891d67bb4fd4f5ce58cd6ed86803c" -dependencies = [ - "bytemuck", - "byteorder", - "color_quant", - "exr", - "gif", - "jpeg-decoder", - "num-rational", - "num-traits", - "png", - "scoped_threadpool", - "tiff", -] - -[[package]] -name = "indexmap" -version = "1.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" -dependencies = [ - "autocfg", - "hashbrown", - "serde", -] - -[[package]] -name = "inlinable_string" -version = "0.1.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb" - -[[package]] -name = "inout" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" -dependencies = [ - "generic-array", -] - -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "ipnet" -version = "2.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f88c5561171189e69df9d98bcf18fd5f9558300f7ea7b801eb8a0fd748bd8745" - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" - -[[package]] -name = "jobserver" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" -dependencies = [ - "libc", -] - -[[package]] -name = "jpeg-decoder" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9478aa10f73e7528198d75109c8be5cd7d15fb530238040148d5f9a22d4c5b3b" -dependencies = [ - "rayon", -] - -[[package]] -name = "js-sys" -version = "0.3.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "jsonwebtoken" -version = "8.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" -dependencies = [ - "base64 0.21.2", - "pem", - "ring", - "serde", - "serde_json", - "simple_asn1", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "lebe" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" - -[[package]] -name = "libc" -version = "0.2.137" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" - -[[package]] -name = "libwebp-sys" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439fd1885aa28937e7edcd68d2e793cb4a22f8733460d2519fbafd2b215672bf" -dependencies = [ - "cc", -] - -[[package]] -name = "link-cplusplus" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369" -dependencies = [ - "cc", -] - -[[package]] -name = "lock_api" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "loom" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" -dependencies = [ - "cfg-if", - "generator", - "scoped-tls", - "serde", - "serde_json", - "tracing", - "tracing-subscriber", -] - -[[package]] -name = "matchers" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" -dependencies = [ - "regex-automata", -] - -[[package]] -name = "memchr" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" - -[[package]] -name = "memoffset" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" -dependencies = [ - "autocfg", -] - -[[package]] -name = "migrations_internals" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b4fc84e4af020b837029e017966f86a1c2d5e83e64b589963d5047525995860" -dependencies = [ - "diesel", -] - -[[package]] -name = "migrations_macros" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9753f12909fd8d923f75ae5c3258cae1ed3c8ec052e1b38c93c21a6d157f789c" -dependencies = [ - "migrations_internals", - "proc-macro2", - "quote", - "syn 1.0.103", -] - -[[package]] -name = "mime" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" - -[[package]] -name = "miniz_oxide" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34" -dependencies = [ - "adler", -] - -[[package]] -name = "miniz_oxide" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" -dependencies = [ - "adler", -] - -[[package]] -name = "mio" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" -dependencies = [ - "libc", - "log", - "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.42.0", -] - -[[package]] -name = "multer" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ed4198ce7a4cbd2a57af78d28c6fbb57d81ac5f1d6ad79ac6c5587419cbdf22" -dependencies = [ - "bytes", - "encoding_rs", - "futures-util", - "http", - "httparse", - "log", - "memchr", - "mime", - "spin 0.9.4", - "tokio", - "tokio-util", - "version_check", -] - -[[package]] -name = "nanorand" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" -dependencies = [ - "getrandom", -] - -[[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 = "nu-ansi-term" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" -dependencies = [ - "overload", - "winapi", -] - -[[package]] -name = "num-bigint" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-integer" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" -dependencies = [ - "autocfg", - "num-traits", -] - -[[package]] -name = "num-rational" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "openssl" -version = "0.10.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12fc0523e3bd51a692c8850d075d74dc062ccf251c0110668cbd921917118a13" -dependencies = [ - "bitflags", - "cfg-if", - "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 1.0.103", -] - -[[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.77" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b03b84c3b2d099b81f0953422b4d4ad58761589d0229b5506356afca05a3670a" -dependencies = [ - "autocfg", - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - -[[package]] -name = "parking_lot" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-sys 0.42.0", -] - -[[package]] -name = "pear" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e44241c5e4c868e3eaa78b7c1848cadd6344ed4f54d029832d32b415a58702" -dependencies = [ - "inlinable_string", - "pear_codegen", - "yansi", -] - -[[package]] -name = "pear_codegen" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82a5ca643c2303ecb740d506539deba189e16f2754040a42901cd8105d0282d0" -dependencies = [ - "proc-macro2", - "proc-macro2-diagnostics", - "quote", - "syn 1.0.103", -] - -[[package]] -name = "pem" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c64931a1a212348ec4f3b4362585eca7159d0d09cbdf4a7f74f02173596fd4" -dependencies = [ - "base64 0.13.1", -] - -[[package]] -name = "percent-encoding" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" - -[[package]] -name = "pin-project" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.103", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkg-config" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" - -[[package]] -name = "png" -version = "0.17.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f0e7f4c94ec26ff209cee506314212639d6c91b80afb82984819fafce9df01c" -dependencies = [ - "bitflags", - "crc32fast", - "flate2", - "miniz_oxide 0.5.4", -] - -[[package]] -name = "polyval" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef234e08c11dfcb2e56f79fd70f6f2eb7f025c0ce2333e82f4f0518ecad30c6" -dependencies = [ - "cfg-if", - "cpufeatures", - "opaque-debug", - "universal-hash", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" - -[[package]] -name = "pq-sys" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b845d6d8ec554f972a2c5298aad68953fd64e7441e846075450b44656a016d1" -dependencies = [ - "vcpkg", -] - -[[package]] -name = "proc-macro-hack" -version = "0.5.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" - -[[package]] -name = "proc-macro2" -version = "1.0.59" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aeca18b86b413c660b781aa319e4e2648a3e6f9eadc9b47e9038e6fe9f3451b" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "proc-macro2-diagnostics" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bf29726d67464d49fa6224a1d07936a8c08bb3fba727c7493f6cf1616fdaada" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.103", - "version_check", - "yansi", -] - -[[package]] -name = "quote" -version = "1.0.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "r2d2" -version = "0.8.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93" -dependencies = [ - "log", - "parking_lot", - "scheduled-thread-pool", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rayon" -version = "1.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d" -dependencies = [ - "autocfg", - "crossbeam-deque", - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "num_cpus", -] - -[[package]] -name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags", -] - -[[package]] -name = "ref-cast" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53b15debb4f9d60d767cd8ca9ef7abb2452922f3214671ff052defc7f3502c44" -dependencies = [ - "ref-cast-impl", -] - -[[package]] -name = "ref-cast-impl" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abfa8511e9e94fd3de6585a3d3cd00e01ed556dc9814829280af0e8dc72a8f36" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.103", -] - -[[package]] -name = "regex" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.6.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" - -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - -[[package]] -name = "reqwest" -version = "0.11.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68cc60575865c7831548863cc02356512e3f1dc2f3f82cb837d7fc4cc8f3c97c" -dependencies = [ - "base64 0.13.1", - "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", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "winreg", -] - -[[package]] -name = "ring" -version = "0.16.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" -dependencies = [ - "cc", - "libc", - "once_cell", - "spin 0.5.2", - "untrusted", - "web-sys", - "winapi", -] - -[[package]] -name = "rocket" -version = "0.5.0-rc.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98ead083fce4a405feb349cf09abdf64471c6077f14e0ce59364aa90d4b99317" -dependencies = [ - "async-stream", - "async-trait", - "atomic", - "atty", - "binascii", - "bytes", - "either", - "figment", - "futures", - "indexmap", - "log", - "memchr", - "multer", - "num_cpus", - "parking_lot", - "pin-project-lite", - "rand", - "ref-cast", - "rocket_codegen", - "rocket_http", - "serde", - "serde_json", - "state", - "tempfile", - "time 0.3.17", - "tokio", - "tokio-stream", - "tokio-util", - "ubyte", - "version_check", - "yansi", -] - -[[package]] -name = "rocket_codegen" -version = "0.5.0-rc.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6aeb6bb9c61e9cd2c00d70ea267bf36f76a4cc615e5908b349c2f9d93999b47" -dependencies = [ - "devise", - "glob", - "indexmap", - "proc-macro2", - "quote", - "rocket_http", - "syn 1.0.103", - "unicode-xid", -] - -[[package]] -name = "rocket_cors" -version = "0.6.0-alpha1" -source = "git+https://github.com/lawliet89/rocket_cors?branch=master#c17e8145baa4790319fdb6a473e465b960f55e7c" -dependencies = [ - "http", - "log", - "regex", - "rocket", - "serde", - "serde_derive", - "unicase", - "unicase_serde", - "url", -] - -[[package]] -name = "rocket_http" -version = "0.5.0-rc.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ded65d127954de3c12471630bf4b81a2792f065984461e65b91d0fdaafc17a2" -dependencies = [ - "cookie", - "either", - "futures", - "http", - "hyper", - "indexmap", - "log", - "memchr", - "pear", - "percent-encoding", - "pin-project-lite", - "ref-cast", - "serde", - "smallvec", - "stable-pattern", - "state", - "time 0.3.17", - "tokio", - "uncased", -] - -[[package]] -name = "rocket_sync_db_pools" -version = "0.1.0-rc.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fa48b6ab25013e9812f1b0c592741900b3a2a83c0936292e0565c0ac842f558" -dependencies = [ - "diesel", - "r2d2", - "rocket", - "rocket_sync_db_pools_codegen", - "serde", - "tokio", -] - -[[package]] -name = "rocket_sync_db_pools_codegen" -version = "0.1.0-rc.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "280ef2d232923e69cb93da156972eb5476a7cce5ba44843f6608f46a4abf7aab" -dependencies = [ - "devise", - "quote", -] - -[[package]] -name = "rustversion" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" - -[[package]] -name = "ryu" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" - -[[package]] -name = "schannel" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" -dependencies = [ - "lazy_static", - "windows-sys 0.36.1", -] - -[[package]] -name = "scheduled-thread-pool" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "977a7519bff143a44f842fd07e80ad1329295bd71686457f18e496736f4bf9bf" -dependencies = [ - "parking_lot", -] - -[[package]] -name = "scoped-tls" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" - -[[package]] -name = "scoped_threadpool" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "scratch" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" - -[[package]] -name = "security-framework" -version = "2.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" -dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "seed_data" -version = "0.1.0" -dependencies = [ - "chrono", - "diesel", - "dotenv", - "server", -] - -[[package]] -name = "serde" -version = "1.0.147" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.147" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.103", -] - -[[package]] -name = "serde_json" -version = "1.0.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "server" -version = "0.1.0" -dependencies = [ - "chrono", - "diesel", - "diesel-derive-enum", - "diesel_migrations", - "dotenv", - "dotenv_codegen", - "figment", - "image", - "itertools", - "jsonwebtoken", - "once_cell", - "reqwest", - "rocket", - "rocket_cors", - "rocket_sync_db_pools", - "serde", - "serde_json", - "strum", - "uuid", - "webp", -] - -[[package]] -name = "sha2" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "sharded-slab" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "signal-hook-registry" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" -dependencies = [ - "libc", -] - -[[package]] -name = "simple_asn1" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" -dependencies = [ - "num-bigint", - "num-traits", - "thiserror", - "time 0.3.17", -] - -[[package]] -name = "slab" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" -dependencies = [ - "autocfg", -] - -[[package]] -name = "smallvec" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" - -[[package]] -name = "socket2" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" -dependencies = [ - "libc", - "winapi", -] - -[[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.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09" -dependencies = [ - "lock_api", -] - -[[package]] -name = "stable-pattern" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4564168c00635f88eaed410d5efa8131afa8d8699a612c80c455a0ba05c21045" -dependencies = [ - "memchr", -] - -[[package]] -name = "state" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbe866e1e51e8260c9eed836a042a5e7f6726bb2b411dffeaa712e19c388f23b" -dependencies = [ - "loom", -] - -[[package]] -name = "strum" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" -dependencies = [ - "strum_macros", -] - -[[package]] -name = "strum_macros" -version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "rustversion", - "syn 1.0.103", -] - -[[package]] -name = "subtle" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" - -[[package]] -name = "syn" -version = "1.0.103" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "tempfile" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" -dependencies = [ - "cfg-if", - "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", -] - -[[package]] -name = "termcolor" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "thiserror" -version = "1.0.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.103", -] - -[[package]] -name = "thread_local" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" -dependencies = [ - "once_cell", -] - -[[package]] -name = "threadpool" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" -dependencies = [ - "num_cpus", -] - -[[package]] -name = "tiff" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7259662e32d1e219321eb309d5f9d898b779769d81b76e762c07c8e5d38fcb65" -dependencies = [ - "flate2", - "jpeg-decoder", - "weezl", -] - -[[package]] -name = "time" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" -dependencies = [ - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi", -] - -[[package]] -name = "time" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376" -dependencies = [ - "itoa", - "serde", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" - -[[package]] -name = "time-macros" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2" -dependencies = [ - "time-core", -] - -[[package]] -name = "tinyvec" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" - -[[package]] -name = "tokio" -version = "1.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76ce4a75fb488c605c54bf610f221cea8b0dafb53333c1a67e8ee199dcd2ae3" -dependencies = [ - "autocfg", - "bytes", - "libc", - "memchr", - "mio", - "num_cpus", - "pin-project-lite", - "signal-hook-registry", - "socket2", - "tokio-macros", - "winapi", -] - -[[package]] -name = "tokio-macros" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.103", -] - -[[package]] -name = "tokio-native-tls" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" -dependencies = [ - "native-tls", - "tokio", -] - -[[package]] -name = "tokio-stream" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d660770404473ccd7bc9f8b28494a811bc18542b915c0855c51e8f419d5223ce" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", - "tracing", -] - -[[package]] -name = "toml" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" -dependencies = [ - "serde", -] - -[[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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" -dependencies = [ - "cfg-if", - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.103", -] - -[[package]] -name = "tracing-core" -version = "0.1.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" -dependencies = [ - "once_cell", - "valuable", -] - -[[package]] -name = "tracing-log" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" -dependencies = [ - "lazy_static", - "log", - "tracing-core", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" -dependencies = [ - "matchers", - "nu-ansi-term", - "once_cell", - "regex", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log", -] - -[[package]] -name = "try-lock" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" - -[[package]] -name = "typenum" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" - -[[package]] -name = "ubyte" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c81f0dae7d286ad0d9366d7679a77934cfc3cf3a8d67e82669794412b2368fe6" -dependencies = [ - "serde", -] - -[[package]] -name = "uncased" -version = "0.9.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09b01702b0fd0b3fadcf98e098780badda8742d4f4a7676615cad90e8ac73622" -dependencies = [ - "serde", - "version_check", -] - -[[package]] -name = "unicase" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" -dependencies = [ - "version_check", -] - -[[package]] -name = "unicase_serde" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ef53697679d874d69f3160af80bc28de12730a985d57bdf2b47456ccb8b11f1" -dependencies = [ - "serde", - "unicase", -] - -[[package]] -name = "unicode-bidi" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" - -[[package]] -name = "unicode-ident" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" - -[[package]] -name = "unicode-normalization" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unicode-width" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" - -[[package]] -name = "unicode-xid" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" - -[[package]] -name = "universal-hash" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d3160b73c9a19f7e2939a2fdad446c57c1bbbbf4d919d3213ff1267a580d8b5" -dependencies = [ - "crypto-common", - "subtle", -] - -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - -[[package]] -name = "url" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", -] - -[[package]] -name = "uuid" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "345444e32442451b267fc254ae85a209c64be56d2890e601a0c37ff0c3c5ecd2" -dependencies = [ - "getrandom", - "rand", - "uuid-macro-internal", -] - -[[package]] -name = "uuid-macro-internal" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f67b459f42af2e6e1ee213cb9da4dbd022d3320788c3fb3e1b893093f1e45da" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.18", -] - -[[package]] -name = "valuable" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "want" -version = "0.3.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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn 1.0.103", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.103", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" - -[[package]] -name = "web-sys" -version = "0.3.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "webp" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf022f821f166079a407d000ab57e84de020e66ffbbf4edde999bc7d6e371cae" -dependencies = [ - "image", - "libwebp-sys", -] - -[[package]] -name = "weezl" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbedf6db9096bc2364adce0ae0aa636dcd89f3c3f2cd67947062aaf0ca2a10ec" -dependencies = [ - "windows_aarch64_msvc 0.32.0", - "windows_i686_gnu 0.32.0", - "windows_i686_msvc 0.32.0", - "windows_x86_64_gnu 0.32.0", - "windows_x86_64_msvc 0.32.0", -] - -[[package]] -name = "windows-sys" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" -dependencies = [ - "windows_aarch64_msvc 0.36.1", - "windows_i686_gnu 0.36.1", - "windows_i686_msvc 0.36.1", - "windows_x86_64_gnu 0.36.1", - "windows_x86_64_msvc 0.36.1", -] - -[[package]] -name = "windows-sys" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc 0.42.0", - "windows_i686_gnu 0.42.0", - "windows_i686_msvc 0.42.0", - "windows_x86_64_gnu 0.42.0", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc 0.42.0", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8e92753b1c443191654ec532f14c199742964a061be25d77d7a96f09db20bf5" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" - -[[package]] -name = "windows_i686_gnu" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a711c68811799e017b6038e0922cb27a5e2f43a2ddb609fe0b6f3eeda9de615" - -[[package]] -name = "windows_i686_gnu" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" - -[[package]] -name = "windows_i686_gnu" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" - -[[package]] -name = "windows_i686_msvc" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c11bb1a02615db74680b32a68e2d61f553cc24c4eb5b4ca10311740e44172" - -[[package]] -name = "windows_i686_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" - -[[package]] -name = "windows_i686_msvc" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c912b12f7454c6620635bbff3450962753834be2a594819bd5e945af18ec64bc" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "504a2476202769977a040c6364301a3f65d0cc9e3fb08600b2bda150a0488316" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" - -[[package]] -name = "winreg" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" -dependencies = [ - "winapi", -] - -[[package]] -name = "yansi" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" diff --git a/backend/Cargo.toml b/backend/Cargo.toml deleted file mode 100644 index b0dc95724..000000000 --- a/backend/Cargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[workspace] - -members = [ - "seed_data", - "server" -] diff --git a/backend/Dockerfile b/backend/Dockerfile deleted file mode 100644 index 4b5276b75..000000000 --- a/backend/Dockerfile +++ /dev/null @@ -1,22 +0,0 @@ -FROM lukemathwalker/cargo-chef:latest-rust-1.68.0 AS chef -WORKDIR /app - -FROM chef AS planner -COPY . . -RUN cargo chef prepare --recipe-path recipe.json - -FROM chef AS builder -COPY --from=planner /app/recipe.json recipe.json -RUN cargo chef cook --release --recipe-path recipe.json -COPY . . -RUN cargo build --release --bin server - -FROM ubuntu -RUN apt update -RUN apt install -y wget libpq5 -RUN wget https://mirrors.edge.kernel.org/ubuntu/pool/main/o/openssl/libssl1.1_1.1.0g-2ubuntu4_amd64.deb \ - && dpkg -i libssl1.1_1.1.0g-2ubuntu4_amd64.deb \ - && rm libssl1.1_1.1.0g-2ubuntu4_amd64.deb - -COPY --from=builder /app/target/release/server / -CMD ["./server"] diff --git a/backend/migrations/00000000000000_diesel_initial_setup/down.sql b/backend/migrations/00000000000000_diesel_initial_setup/down.sql deleted file mode 100644 index a9f526091..000000000 --- a/backend/migrations/00000000000000_diesel_initial_setup/down.sql +++ /dev/null @@ -1,6 +0,0 @@ --- This file was automatically created by Diesel to setup helper functions --- and other internal bookkeeping. This file is safe to edit, any future --- changes will be added to existing projects as new migrations. - -DROP FUNCTION IF EXISTS diesel_manage_updated_at(_tbl regclass); -DROP FUNCTION IF EXISTS diesel_set_updated_at(); diff --git a/backend/migrations/00000000000000_diesel_initial_setup/up.sql b/backend/migrations/00000000000000_diesel_initial_setup/up.sql deleted file mode 100644 index d68895b1a..000000000 --- a/backend/migrations/00000000000000_diesel_initial_setup/up.sql +++ /dev/null @@ -1,36 +0,0 @@ --- This file was automatically created by Diesel to setup helper functions --- and other internal bookkeeping. This file is safe to edit, any future --- changes will be added to existing projects as new migrations. - - - - --- Sets up a trigger for the given table to automatically set a column called --- `updated_at` whenever the row is modified (unless `updated_at` was included --- in the modified columns) --- --- # Example --- --- ```sql --- CREATE TABLE users (id SERIAL PRIMARY KEY, updated_at TIMESTAMP NOT NULL DEFAULT NOW()); --- --- SELECT diesel_manage_updated_at('users'); --- ``` -CREATE OR REPLACE FUNCTION diesel_manage_updated_at(_tbl regclass) RETURNS VOID AS $$ -BEGIN - EXECUTE format('CREATE TRIGGER set_updated_at BEFORE UPDATE ON %s - FOR EACH ROW EXECUTE PROCEDURE diesel_set_updated_at()', _tbl); -END; -$$ LANGUAGE plpgsql; - -CREATE OR REPLACE FUNCTION diesel_set_updated_at() RETURNS trigger AS $$ -BEGIN - IF ( - NEW IS DISTINCT FROM OLD AND - NEW.updated_at IS NOT DISTINCT FROM OLD.updated_at - ) THEN - NEW.updated_at := current_timestamp; - END IF; - RETURN NEW; -END; -$$ LANGUAGE plpgsql; diff --git a/backend/migrations/2021-12-07-112918_create_users/down.sql b/backend/migrations/2021-12-07-112918_create_users/down.sql deleted file mode 100644 index cc1f647d2..000000000 --- a/backend/migrations/2021-12-07-112918_create_users/down.sql +++ /dev/null @@ -1 +0,0 @@ -DROP TABLE users; diff --git a/backend/migrations/2021-12-07-112918_create_users/up.sql b/backend/migrations/2021-12-07-112918_create_users/up.sql deleted file mode 100644 index ebd7ab8f9..000000000 --- a/backend/migrations/2021-12-07-112918_create_users/up.sql +++ /dev/null @@ -1,13 +0,0 @@ -CREATE TABLE users ( - id SERIAL PRIMARY KEY, - email TEXT NOT NULL, - zid TEXT NOT NULL, - display_name TEXT NOT NULL, - degree_name TEXT NOT NULL, - degree_starting_year INTEGER NOT NULL, - superuser BOOLEAN NOT NULL, - created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP -); - -SELECT diesel_manage_updated_at('users'); diff --git a/backend/migrations/2021-12-07-114233_create_organisations/down.sql b/backend/migrations/2021-12-07-114233_create_organisations/down.sql deleted file mode 100644 index c0f04cf40..000000000 --- a/backend/migrations/2021-12-07-114233_create_organisations/down.sql +++ /dev/null @@ -1 +0,0 @@ -DROP TABLE organisations; diff --git a/backend/migrations/2021-12-07-114233_create_organisations/up.sql b/backend/migrations/2021-12-07-114233_create_organisations/up.sql deleted file mode 100644 index a608b61ff..000000000 --- a/backend/migrations/2021-12-07-114233_create_organisations/up.sql +++ /dev/null @@ -1,9 +0,0 @@ -CREATE TABLE organisations ( - id SERIAL PRIMARY KEY, - name TEXT NOT NULL, - logo BYTEA, - created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP -); - -SELECT diesel_manage_updated_at('organisations'); diff --git a/backend/migrations/2021-12-07-114404_create_organisation_users/down.sql b/backend/migrations/2021-12-07-114404_create_organisation_users/down.sql deleted file mode 100644 index 3677372d8..000000000 --- a/backend/migrations/2021-12-07-114404_create_organisation_users/down.sql +++ /dev/null @@ -1,2 +0,0 @@ -DROP TABLE organisation_users; -DROP TYPE admin_level; diff --git a/backend/migrations/2021-12-07-114404_create_organisation_users/up.sql b/backend/migrations/2021-12-07-114404_create_organisation_users/up.sql deleted file mode 100644 index 25f191ff4..000000000 --- a/backend/migrations/2021-12-07-114404_create_organisation_users/up.sql +++ /dev/null @@ -1,12 +0,0 @@ -CREATE TYPE admin_level AS ENUM ('ReadOnly', 'Director', 'Admin'); - -CREATE TABLE organisation_users ( - id SERIAL PRIMARY KEY, - user_id INTEGER NOT NULL REFERENCES users (id), - organisation_id INTEGER NOT NULL REFERENCES organisations (id), - admin_level admin_level NOT NULL, - created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP -); - -SELECT diesel_manage_updated_at('organisation_users'); diff --git a/backend/migrations/2021-12-07-114733_campaigns/down.sql b/backend/migrations/2021-12-07-114733_campaigns/down.sql deleted file mode 100644 index 4f386f056..000000000 --- a/backend/migrations/2021-12-07-114733_campaigns/down.sql +++ /dev/null @@ -1 +0,0 @@ -DROP TABLE campaigns; diff --git a/backend/migrations/2021-12-07-114733_campaigns/up.sql b/backend/migrations/2021-12-07-114733_campaigns/up.sql deleted file mode 100644 index 1cb6f3150..000000000 --- a/backend/migrations/2021-12-07-114733_campaigns/up.sql +++ /dev/null @@ -1,14 +0,0 @@ -CREATE TABLE campaigns ( - id SERIAL PRIMARY KEY, - organisation_id INTEGER NOT NULL REFERENCES organisations (id), - name TEXT NOT NULL, - cover_image BYTEA, - description TEXT NOT NULL, - starts_at TIMESTAMP NOT NULL, - ends_at TIMESTAMP NOT NULL, - published BOOLEAN NOT NULL, - created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP -); - -SELECT diesel_manage_updated_at('campaigns'); diff --git a/backend/migrations/2021-12-07-114906_roles/down.sql b/backend/migrations/2021-12-07-114906_roles/down.sql deleted file mode 100644 index 0f9306dc2..000000000 --- a/backend/migrations/2021-12-07-114906_roles/down.sql +++ /dev/null @@ -1 +0,0 @@ -DROP TABLE roles; diff --git a/backend/migrations/2021-12-07-114906_roles/up.sql b/backend/migrations/2021-12-07-114906_roles/up.sql deleted file mode 100644 index 4959761ca..000000000 --- a/backend/migrations/2021-12-07-114906_roles/up.sql +++ /dev/null @@ -1,13 +0,0 @@ -CREATE TABLE roles ( - id SERIAL PRIMARY KEY, - campaign_id INTEGER NOT NULL REFERENCES campaigns (id), - name TEXT NOT NULL, - description TEXT, - min_available INTEGER NOT NULL, - max_available INTEGER NOT NULL, - finalised BOOLEAN NOT NULL DEFAULT FALSE, - created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP -); - -SELECT diesel_manage_updated_at('roles'); diff --git a/backend/migrations/2021-12-07-115409_questions/down.sql b/backend/migrations/2021-12-07-115409_questions/down.sql deleted file mode 100644 index 17135d605..000000000 --- a/backend/migrations/2021-12-07-115409_questions/down.sql +++ /dev/null @@ -1 +0,0 @@ -DROP TABLE questions; diff --git a/backend/migrations/2021-12-07-115409_questions/up.sql b/backend/migrations/2021-12-07-115409_questions/up.sql deleted file mode 100644 index 19cd4c396..000000000 --- a/backend/migrations/2021-12-07-115409_questions/up.sql +++ /dev/null @@ -1,12 +0,0 @@ -CREATE TABLE questions ( - id SERIAL PRIMARY KEY, - role_id INTEGER NOT NULL REFERENCES roles (id), - title TEXT NOT NULL, - description TEXT, - max_bytes INTEGER NOT NULL, - required BOOLEAN NOT NULL, - created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP -); - -SELECT diesel_manage_updated_at('questions'); diff --git a/backend/migrations/2021-12-07-115608_applications/down.sql b/backend/migrations/2021-12-07-115608_applications/down.sql deleted file mode 100644 index 0739143e4..000000000 --- a/backend/migrations/2021-12-07-115608_applications/down.sql +++ /dev/null @@ -1,2 +0,0 @@ -DROP TABLE applications; -DROP TYPE application_status; diff --git a/backend/migrations/2021-12-07-115608_applications/up.sql b/backend/migrations/2021-12-07-115608_applications/up.sql deleted file mode 100644 index 49d6292ba..000000000 --- a/backend/migrations/2021-12-07-115608_applications/up.sql +++ /dev/null @@ -1,12 +0,0 @@ -CREATE TYPE application_status AS ENUM ('Pending', 'Rejected', 'Success'); - -CREATE TABLE applications ( - id SERIAL PRIMARY KEY, - user_id INTEGER NOT NULL REFERENCES users (id), - role_id INTEGER NOT NULL REFERENCES roles (id), - status application_status NOT NULL, - created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP -); - -SELECT diesel_manage_updated_at('applications'); diff --git a/backend/migrations/2021-12-07-115832_answers/down.sql b/backend/migrations/2021-12-07-115832_answers/down.sql deleted file mode 100644 index 90ff272a5..000000000 --- a/backend/migrations/2021-12-07-115832_answers/down.sql +++ /dev/null @@ -1 +0,0 @@ -DROP TABLE answers; diff --git a/backend/migrations/2021-12-07-115832_answers/up.sql b/backend/migrations/2021-12-07-115832_answers/up.sql deleted file mode 100644 index b3f502136..000000000 --- a/backend/migrations/2021-12-07-115832_answers/up.sql +++ /dev/null @@ -1,10 +0,0 @@ -CREATE TABLE answers ( - id SERIAL PRIMARY KEY, - application_id INTEGER NOT NULL REFERENCES applications (id), - question_id INTEGER NOT NULL REFERENCES questions (id), - description TEXT NOT NULL, - created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP -); - -SELECT diesel_manage_updated_at('answers'); diff --git a/backend/migrations/2021-12-07-115931_comments/down.sql b/backend/migrations/2021-12-07-115931_comments/down.sql deleted file mode 100644 index 9ef7d1265..000000000 --- a/backend/migrations/2021-12-07-115931_comments/down.sql +++ /dev/null @@ -1 +0,0 @@ -DROP TABLE comments; diff --git a/backend/migrations/2021-12-07-115931_comments/up.sql b/backend/migrations/2021-12-07-115931_comments/up.sql deleted file mode 100644 index c286ce298..000000000 --- a/backend/migrations/2021-12-07-115931_comments/up.sql +++ /dev/null @@ -1,10 +0,0 @@ -CREATE TABLE comments ( - id SERIAL PRIMARY KEY, - application_id INTEGER NOT NULL REFERENCES applications (id), - commenter_user_id INTEGER NOT NULL REFERENCES users (id), - description TEXT NOT NULL, - created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP -); - -SELECT diesel_manage_updated_at('comments'); diff --git a/backend/migrations/2021-12-07-120033_ratings/down.sql b/backend/migrations/2021-12-07-120033_ratings/down.sql deleted file mode 100644 index c1ae6185b..000000000 --- a/backend/migrations/2021-12-07-120033_ratings/down.sql +++ /dev/null @@ -1 +0,0 @@ -DROP TABLE ratings; diff --git a/backend/migrations/2021-12-07-120033_ratings/up.sql b/backend/migrations/2021-12-07-120033_ratings/up.sql deleted file mode 100644 index 432da2ff9..000000000 --- a/backend/migrations/2021-12-07-120033_ratings/up.sql +++ /dev/null @@ -1,10 +0,0 @@ -CREATE TABLE ratings ( - id SERIAL PRIMARY KEY, - application_id INTEGER NOT NULL REFERENCES applications (id), - rater_user_id INTEGER NOT NULL REFERENCES users (id), - rating INTEGER NOT NULL, - created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP -); - -SELECT diesel_manage_updated_at('ratings'); diff --git a/backend/migrations/2022-05-30-145617_questions/down.sql b/backend/migrations/2022-05-30-145617_questions/down.sql deleted file mode 100644 index e69de29bb..000000000 diff --git a/backend/migrations/2022-05-30-145617_questions/up.sql b/backend/migrations/2022-05-30-145617_questions/up.sql deleted file mode 100644 index c835b42de..000000000 --- a/backend/migrations/2022-05-30-145617_questions/up.sql +++ /dev/null @@ -1,20 +0,0 @@ -ALTER TABLE IF EXISTS questions - DROP CONSTRAINT questions_role_id_fkey; - -ALTER TABLE IF EXISTS questions - ALTER COLUMN role_id TYPE INTEGER[] - USING array[role_id]::INTEGER[]; - -ALTER TABLE IF EXISTS questions - RENAME COLUMN role_id TO role_ids; - -CREATE TABLE IF NOT EXISTS questions ( - id SERIAL PRIMARY KEY, - role_ids INTEGER[] NOT NULL, - title TEXT NOT NULL, - description TEXT, - max_bytes INTEGER NOT NULL, - required BOOLEAN NOT NULL, - created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP -); diff --git a/backend/migrations/2022-11-21-043159_application_private_statuses/down.sql b/backend/migrations/2022-11-21-043159_application_private_statuses/down.sql deleted file mode 100644 index 912ef129b..000000000 --- a/backend/migrations/2022-11-21-043159_application_private_statuses/down.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE applications -DROP COLUMN private_status; diff --git a/backend/migrations/2022-11-21-043159_application_private_statuses/up.sql b/backend/migrations/2022-11-21-043159_application_private_statuses/up.sql deleted file mode 100644 index 9b9efd676..000000000 --- a/backend/migrations/2022-11-21-043159_application_private_statuses/up.sql +++ /dev/null @@ -1,9 +0,0 @@ -ALTER TABLE applications -ADD COLUMN private_status application_status; - -UPDATE applications -SET private_status = status; - -ALTER TABLE applications -ALTER COLUMN status -SET NOT NULL; diff --git a/backend/migrations/2022-12-04-065103_image_files/down.sql b/backend/migrations/2022-12-04-065103_image_files/down.sql deleted file mode 100644 index 1ba72d005..000000000 --- a/backend/migrations/2022-12-04-065103_image_files/down.sql +++ /dev/null @@ -1,5 +0,0 @@ -ALTER TABLE organisations -ALTER COLUMN logo TYPE BYTEA USING NULL; - -ALTER TABLE campaigns -ALTER COLUMN cover_image TYPE BYTEA USING NULL; diff --git a/backend/migrations/2022-12-04-065103_image_files/up.sql b/backend/migrations/2022-12-04-065103_image_files/up.sql deleted file mode 100644 index ecafde660..000000000 --- a/backend/migrations/2022-12-04-065103_image_files/up.sql +++ /dev/null @@ -1,5 +0,0 @@ -ALTER TABLE organisations -ALTER COLUMN logo TYPE TEXT USING NULL; - -ALTER TABLE campaigns -ALTER COLUMN cover_image TYPE TEXT USING NULL; diff --git a/backend/migrations/2023-06-07-042751_user_gender/down.sql b/backend/migrations/2023-06-07-042751_user_gender/down.sql deleted file mode 100644 index 0c5e3ef5a..000000000 --- a/backend/migrations/2023-06-07-042751_user_gender/down.sql +++ /dev/null @@ -1,4 +0,0 @@ -ALTER TABLE users -DROP COLUMN gender; - -DROP TYPE user_gender; diff --git a/backend/migrations/2023-06-07-042751_user_gender/up.sql b/backend/migrations/2023-06-07-042751_user_gender/up.sql deleted file mode 100644 index d6007cd33..000000000 --- a/backend/migrations/2023-06-07-042751_user_gender/up.sql +++ /dev/null @@ -1,4 +0,0 @@ -CREATE TYPE user_gender AS ENUM ('Female', 'Male', 'Unspecified'); - -ALTER TABLE users - ADD COLUMN gender user_gender DEFAULT 'Unspecified' NOT NULL; diff --git a/backend/migrations/2023-09-20-052638_user_pronouns/down.sql b/backend/migrations/2023-09-20-052638_user_pronouns/down.sql deleted file mode 100644 index 6cc4cb645..000000000 --- a/backend/migrations/2023-09-20-052638_user_pronouns/down.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE users -DROP COLUMN pronouns; diff --git a/backend/migrations/2023-09-20-052638_user_pronouns/up.sql b/backend/migrations/2023-09-20-052638_user_pronouns/up.sql deleted file mode 100644 index ef54ae9c3..000000000 --- a/backend/migrations/2023-09-20-052638_user_pronouns/up.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE users - ADD COLUMN pronouns TEXT DEFAULT '' NOT NULL; diff --git a/backend/scripts/become_super_user.sh b/backend/scripts/become_super_user.sh deleted file mode 100755 index 1f15a822f..000000000 --- a/backend/scripts/become_super_user.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash - -echo "Starting the script" -echo "====================" -echo "what is the email for the account?" -read SUPERUSER_EMAIL - - -echo "make $SUPERUSER_EMAIL a superuser? (y/n)" -read SUPERUSER_ANSWER -if [ "$SUPERUSER_ANSWER" == "n" ]; then - echo "skipping superuser creation" - exit -fi - - - -# expose env variables from .env -if [ -f .env ] -then - export $(cat .env | sed 's/#.*//g' | xargs) -else - echo "no .env file found" - exit -fi - -echo "db url is $DATABASE_URL" - -psql $DATABASE_URL << EOF - - UPDATE users SET superuser = true WHERE email = '$SUPERUSER_EMAIL'; - -EOF diff --git a/backend/scripts/seed.sh b/backend/scripts/seed.sh deleted file mode 100755 index 4054cd63b..000000000 --- a/backend/scripts/seed.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -echo "WARNING - this will WIPE your local database" -echo "WARNING - this will WIPE your local changes to database/schema.rs" -echo "Are you sure you want to continue? (y/n)" -read answer -if [ "$answer" != "y" ]; then - echo "Aborting" - exit 1 -fi - -echo "Deleting images directory" -rm -rf images - -cd server/src && diesel database reset - -cd ../../seed_data && cargo run --bin seed_data - -mv images .. diff --git a/backend/seed_data/Cargo.toml b/backend/seed_data/Cargo.toml deleted file mode 100644 index 1daa00552..000000000 --- a/backend/seed_data/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "seed_data" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -server = { path="../server" } -diesel = "1.4.8" -chrono = "0.4.23" -dotenv = "0.15.0" diff --git a/backend/seed_data/assets/180DC.png b/backend/seed_data/assets/180DC.png deleted file mode 100644 index beccfcfc5e4f994dca87beaa90b9ec7221aa955b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 216499 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�@#NBT(~Uyln3!`tMsx>HSu6aO%2!|J%zK%6I_K# z->T@Zk*mPI*{6|w11i4VPK%y#56-Z`Zd|EUI*N#$-P5_QeABMWTQvVyN74Y z%&52Nso|~lAAHj#!w0|%tAEALmp(BtIkKXa1-4}gB~E~)2G?A{bgtv|dkd(|JPo6n zeVRii3LV(ISCgbzBLkHKb^dP~!kqc!))Sq?uk)llVmbe8#QmN_Lag== z3GV^rK<)@!zaxCVe0E0djAS&lR;OA-6J+Z|GM7dE@v3I_7>T+$ML^c%BH3%f-x+A;C7D9Fg~7} zEg$~+&B{?Sgjm_c8D2`wCe^L1IKJr-etOc^m9Q#TmIU2e=foyYjB~MGF)SpZz*VE#_^oSKr*pB9wj*doy_YIy2^hP! z@fWx&qKgx(UO{M6+r+sc+O)-=6iXlS!{kv}o91-`oabZj6V~rDA!m1y*|KTKrudm3 z5(Q@OSF+1Ja}NXFrXGFRQ?C_6#P0osB~_>>At{YYdEz5`LkPm;9Qz&q8}kx#Px7B# z9L$ajwX>nV$Vjq``LYuk9MEv?1mmu|@dI@{X&QFm#^3&Pu45`}VB}yaw^}n%_q?24 zDw^xaZuRq>;LBfWbWO@n)>m1xDz%py>xCht6UPpIJbM`MDTq<=N8EIJ!#oxr+Ldlh zdGJijbXh$)P)UkwSF@uu7oLOMt%c?aC8gl0hcJ3g97mGJVw~FjuLbuM4ari0`u*6q z=WhvMwx^_e7H-Px5*?G`k6HQqR48P{n=n_1$^>(J(!F-wZBSSaP0JT6HZk2#)+DR+^Q#=g z!snb(WM;e1C6i0kY?Us9Q%7psY!~6G_6)I8dj~H1dh&c1k}K^F?`#3rcKwSA*)4}} zTIBaIs$jGh)wG{8wGOg0onSCws4PR=TpM<3kH~x$#+6xeAVu;*?G$pEqEis4wj5i0JI3W@Y5-cfikda1EBXB?_s}zxo8IfMhuvMfUCVr8@-kwfHb0?AROz49>kR>Nv-|Rqda$t&UvHK4w7p-C=Q*Bm113%FzI9>2P>7$f8lbaSA zX$Mt3SQaG(-7v|Z+xjuCD!^hchY9;MrGi>(AgLBVPvDQXot1IB|I1B<4gj!l{sFA* z$zyJ~G)EFM>?(QXA!luqMb^M%MvcW%)CIrop!L@0!-x^u22^Fn<>fE@{!Lq{yi56K z1OjE|tR*0jaFScDO&Mt#_^)%>S|4*6p@rCq9ntEo>KURD_@V7JMA~dcQ75H&O*j|{ z*v)7%k##&IM*w>=T8*|-(2emq-R zjYlS*Wr5$HKd3TYFDvI~)frtLd*RAW)a6nZYy&!Q|BGP{IqaGLuLWr3Oy}z@^meMN zD%5{dSmJW-(Q;ncT<|*}%~$0#|C+aDUE{_?O1=7b7#+tSnuBb}>SMi3*Ef5Zb?dF* zQZdNwsp!(Btqe3NzDI(z65Br!4+&6^ye0WK^`TzFPsU1>1f+9|Yf2;4LmA7lR_hsg;VIO#+!j{fRgnSG9ZhPWaJ0;3z?(?cgzwIL>x#hr9;px#e zD{Y`Z3VcfK|{>bMKUdGl$Ul@;r~)66}p!?Ec~&Zj%4*kt}Ui+Nkkz`YH8v{Tcn}IHG)| z*lw9(?(>U}|5kl2c>;>n7i1W;T>)=IeGHFow?CsXt06L%0_D9V1zXYmI8IA zd!Bh6{xK$V3P>WE_=K&G-(|5kknlG&|C0P)qCjuU);4H9`^Bobw3#;J<#g<8Z@#9W zXAxqu*s(+IzmMu^aBY2W&a=4P_hD}%D*mdzCC`tpEntz`O(4-m10Ee^v(2c#Q-f#* zJCernEv2Oyo#j&4x_j^gPu`(!Rp`l4m@Gq$?Bq%%6EADmP6Lf6Yrdb2#+xcya!U_# z=nbk&H)rC}pAH7KAzas%)vl;V#n}2wg#V}k9mo^PAeQ{Xy@yiur|9xFqzbqF5$EMB zCJ|@onNfQtMCgNeE8FtY?ZZ^O_HsD-HG1Bmd~PBRigThY5`Je=HWy)&5Yap~-^f*$ zlF7O(2vlsPt5j_U^Ll-0sOg-m?O=}CHx~KsP(y7(f_H;V8Nux)KUJA6sYI+eYfZ@M zDA}h@$A95>CNa|w4vBK_+n3`>DF5_jF!^xkG7k9ZYS#-={k#!OSXHb>Xl5V$zlw+E zQj0aK9o&2=D{=ets{rFE?>z@T{9)D@#P=pQpurSto!NJKI&tP8 zc<-T?4b!Oi{X!pn>`FvFysUY4$t0nG%~Y**cTbIT9d9llTP6Qqx}gWsn@Ih%(R?! z(|=)VpyObKhq?Pga+#RwfXBS{`=Qk+K0W?! zJw$ZU!xg`;4%#B4LFm-7Ftu+x%F40+wX6~cX(i2tSQ!*as^DlQ6Ys z9A7Vjv{K!$a_a;xLizgC;Y>7V=+;(+=sV0N(z__0^uqTFrAdl`INPNR^pOGok@sxiM{wG z`&`&bZ z1?qn^5Z3c1JDeLv{=;{_-0uR&Alspw$sHxMc9!HMfo|F8Zthuwlt3H=`Kj2nR^q+Y z4u^X{m}c*ez?*$o!0UIh_||xN;eq_X0aa911B!+4J*vBBkRPKkkK&!hsIy;iKlFD-O zb9o#FBFOGeAgd2O4F|_Ul+EMee&qtUr)R(1n~qWq*x0r)5I#yHO}y7e+6>fhd2hDr z4qKcPr7L6B*2l^kLZ|nBWfa-y)Xj0O^;|NkrgJ$CSTq3KGx#r}aqt>@K$ZQ^bGv3U z%eH45Nz*P3RH2oHXa%lC9~R^S=Q)@zWA<1cwgtOoHjbejb;IT@DIi5a7Ys9Uw_D|Cdsb!nrnUsr~1U+PCA0AK#yK=P`Y0HtP2>oQMC?x%k4n2)N4f$y@ zvJL#=|Bs_KXVvXEVA1Y=&Q^w&&Ia|hKEcOb(gn_{++$uWqLJo9Yk^+H_bOW~LCgIvPa+lv}Nh}#z>LVhj zs1d0sDl_Xqeuq26oa%5xZC?g7WSp8rJCF7kl!3@tkiDArI|7FxZWCAGwAE(pk*Smu zux=1?1GvTzUGB+q4fMHo%j$-vlRADyi&m|a_o*?T6@?y|^geLd-{W{MhALXrxaG5| z*wr72=F5n-Kv{%ZEo`ny*nsDTiY% zxu>fE4L-^XlTj~j`pRvF@=?L?ZIO|IX76Yo34KG}93#H@GUY8E*on?YgA6ulvB!{r9&FLxPjiT2^atB`EV?}* zw#sk^PdmDbzQ#u1O)kl|17anm=@6=%HWi(QwBSO~&AgP8E0h1P zG7b%b!YMMyZz}gCeeKgidEE+zD~bEGD)PJjVyOH0XxMimWpIJR9~HZWqw+`eTT5j$ z^Y(`b0oY7@bXeHn5c<&fO!L+vj{J6z7*@8CdJT>wj&%~43MpSi?`S7#tDMHKL$#m ztt3pWFb-u|^*4=mx?WK3bRiz6rG^S-yuoY-WvDeYA5xz1ZRv6)+HMd>uJlG6tT@+Gau)^Lh-l8E4!ZJlCVT{7(ELF8t-;b1(`@=j2?9Z4%X!dnqbI!nb=LLkzbn!~1Y?*5sItCDA_q(W8}<#KElO zpGh}v`;%tJ>Sg_M#XaY$BeZ&e-5&4jH&GcdG~zpLgXcJuU&-mNa=EJb3-tlErJ9V@!ue$ExrQx`AFElcgi8 zE1aDcXU&{lc|g-+KSb~G#s)_Y(kjmeyVG~vVZ*f6@M3mZZlp$&%sw#A`(HQg9Ya~i z)~@mmTJzb%PPZTtllLWv0q3dQVw-)MZM z&%+tpd!h~2fiT1lV3|>{#~CF^chVhM2{Jq89UOrBy<2DY^@BbQeAZkN#;*I!mdy22 z2*q>i%3a&Q<#ym6GM3-fVapS9HoDQX7w>;0c9hU)`}0#WSroXA^~zl&GsERJZK7KD z^VnSkA;32c{Nop8M&wj#xWqLf&MRvq+316@uoPQ_`))F=7^t z?{`-re!JKh0a#yuYawZc(N1zK^L)Ni*~^;|u4}#}{jj6vm8;hE4#A6R6J^5nOCaA8 z4j;MYLCfze^--7cFEpGqqtYTqD?*?O_QkGq_-3;D4WauBti<_`6qj-kukoDb1!k{} zVO)$RuCeH0Gj^=+BZJWM0}0~;LcVw-jsvcQ=W*_vWigz z@UyGI6nGtDf)x>jqCpQL?>Gn{4>-Ox?CI`cmu5>jQ`~uc<(li@hd6#kE->{tAl3rM z6-u3i6O6fEgsHg;^=NdfG6AuTekFzv{J6;e+68dQ{3-Er*sbs9wz4%0i?ur%Ci$vq z_g*#csA|L*aH&@-6|9_=+RXP-N6r*z%cOVe@5Wz~dGBtlpEx{XpcP`uVRc$ym0lpU z@zy-2w(|tgGG+jtDD%$~QHK>G@}A}|jYVcwvCPGS=#Bi%X2C;FTCM#fl)s7++oziXbqtj{m;(m8~w89xkJLH6& z>j1@?&0MQ{``yIWD z@MQPa5+q<_ZDQV`)~iRgAYz&nxJ6C3b7r` zwe$EU|78G%VzmFtXb|>&+M##G#`jD?iaivTu4*Jj^`i!hBBHoFl#1AFnE58#k0@ zSgu;1JkTi66V3%NI50NyrUMTM%TC77O{qpL8Jc=Mi>FyvnU|aUzV*>C31rA3Zd66= zN6D0h%rN!z?#H%n9X3BrjlWHo?thgnet}A5-P3ks9mzBAX4}VCt`b4-xc8%-?)Cyk zkY6VVw$y1%2Q&Ir;AqnGi65{bg=Dv^T`zhT zWH!(o@_iimV(}Sw*NPWKt_B%)lF#b!;u;lV+T>aZG2$J{726P4%j8QLwg z*W2afK+^0NDz>&G#Jja{_WfcByhQeXMN`F>ZRoNxU1SDXfWZmSIM@#xGMaLIPjxV| zal^EBb9DCng%JN}-9>)qK|PZ*SAwoxjqZ`t>S2b|?_fUfLp!ae&inHBg8LNFCDvpC z+6K{Uky?CPWt<;Ff=hpP@C0sJAA3p=rjkyW{JAl!913-42;r*)VM4zZSKlt;c9#>- zrE)*Kn7ITqQNZHb?i50tcT0)!);er9Z%P|^Wi09i_6dYKj(&NfdpvQap5Tjr?uA4B zKfc~Ftjg{QAKk!KLXizfcej9)^akl}kPuM1rMpW~y1QFiT1n~dlJ4$45AgoZ|D5Yw z*ZICbtUb@necv-{*34U4kMpsPTJvl0MH2Q`EYMR$+OL3tB_o@<>|}6A-JQJNN`4iE($RvXVUmEF`wNShSe2O4sDf|fqWl@veJ`ea zC(S*U|18!8UQ2`3d-u&;92UzJ;o$3EhM}xADAak`mKriG(glJDykK8^*d!)Ku+5^J zu5R4!sd#5J^b4nry3HBC92;5RyAv&7`m(o>q`FfN1cI&DXi(V?ZVznfETBVGIDQ z0D4L}UQK^5_0e{_t`x0z=WKFf&xED}sZYVs;H8(47dY@M*4bN2X1Y@4Qy68(^pV== z$U(euMs1_HJUaY(R{DkWde{~ zv(6X#)(M{0x<5|z-=N|zAuiRo(iPuAK}8hAFJ4A%YzBUL`9gBKGf7Vkr8V8)lY#Mh z+xJ1Ej8W>OsW0D7M8*~Zt{Q> z$s1m`qi8=IM})<_eSw%aeaODlp*;nCsUF~9d9`Ye$EU>X1@tjsJbmI976;!Ao6mPW zWO4>SSfG=_rbCZUXyansfj&KPlm|k$4;c!Q`I{@w)ye7Pb(f?5T6rTVw6-bq`($r& zWYdV#WEm4Zx;>m1wYBTlO@95<^HJiOj5~)9I0h~SMV%G)vdd_Xm{2Cy-+e_>=z&#S8j57btqz&`743)c^~jOQjtVt*dtVsVpNzMIwK{q7Mk6c>>h95hRF=hvOE`z zZjScR9~>(T!<902$gOTmb~8x?s4+B~w!PpP?}|6RmHlA0UwWz^X}wK#JJH~GJQ{p| zpT0pEa6{);A}=H%pC6qjKV3yGP7Iaw`{JlFz8Q-iO^)R;@yb< z`w6I-2VX2)evksjEvxIdWi)5752ohxZ+^eFHI(74e0XS_K6B-oT=^1Z^~L`BZGoJA4gK_0O-Tz!latIN z??_WVDWBjD*$cN5fLUD@P!iE8S_Fi_Z}Tz4M|4%zSTfQ^gIJAVK|2qqx`X_T6Io`}(TsQ$ly{P5ns8-E>W}t*FPft!(|P>XGc| z39y0>(Au^1i!{P0h=mOI$|R{gm|a&j0{5Y7Cgi0a|C_9em4uvWlsrm5nR4Tm?p>N_ z<&P%w?YCd;zXg=iC`r&M*(74UOKMsh(dXu1Xv~;SB8=(U4m$n5;0Dwed%PCrdj>h2 zMun48Y}>?4(~cz#wXZg77_D2rGusO+D+66A_Na($huzw@9pM*l7};-ywer3Mf;|0Z zuc-^#pxtut8IjGvcwBV(>38yL<03J9+O>W%a(kOO5#y6wBv3Kh=sIp-0n*089hLOL zSot6HcYApwb^Cub599zM8s*)*$hP4v(0qWFk|p6`_n?5p1!0812iRS+G^0Ap)etRzr~ z6QI$M%uO={v(x|jcITa>!uYGz<}!>Qy@cECHV2*GaqqMx+xiaHS8-Mwj(mjV1)YI; z9Z->r9h`q=DYUZ3*Au~k8%`+N7dr}9vQ6g>gqdV$`s$)!KUpLg(k(~C0M9D&95FxI z*WH7?Os}iaxX7(MSuyS*gs?a=X(k*N{Yv5}eHJB(@}3IhIUZ}B8hrPgag@Ing|b=y zR;6uArr`XwJvW%SVIgqyG3VrrM;>wi(cNn+Vqp7&%nJb)MxGcp(+X8YU5e?}Fp}P& zMgG;hOu{sf{l}l5$G)l({^n_OrY?^UGsr}Z5S}dXH|Lb>0V9$i=cTNn^^k3@c1W+LnxBZX*bz%Xx`Ppim}nQu?Z_FY0W*rgT!F2qVTXyYYTZOVx%wje zr~140GLdKB+Y9%bV3yONK&aZp`YH^JC-QO(&}+KinDm$O5)s=^B6bp`1d4SN3r#Oe zYq8qgRnrkoSL{w0cTdM4{q#54GgJraRMEvwZa7|Vd^9CTL%1j0Z2NC} zA1~$2(4JY$HZf{+!F}Em$x{nH&CFU8X1IlkimRau`Gqqu-I+4)7bq~&HAhM8y^@4U zPL)EoAgQ#jm|%##0|Khis>&(?MJ2uO@K0tUB_+2EMdQsW(N2eyAJll)CwYAy7k6n| z4PWTSJfZLc3#tjpY5f5oof1xbY!`^Od(T$yyzb2mwd={SUcWJLfs277h0PK7q4Yx& zCnn8=c!otu{mMbdTj?&IAFCyd+Cz(dfj5j)UTVx~pg6G-$PKBiYNhzfnTe=(PLG>& z7%MjmLb9aCR9(zp$^!bHkzy2V@)*_mZVG!b7c0IUm87l+XIFM^_E+t5UbV%^-lsE; zr;1VXmQm1>;YP%g8%k-}9>fl6*4P>W5EvG%@ zd1#+UvUikJboaSusIWs;DEX^+3c41r zK?v%KIpP%^(kVeiwo(*fC zY2p~<09XFFSMZerv^#m$f8^eAYH%Z8$@8x#sr|`kA2pvJ zr1r!9Zjh{Wc>}iKsm>%rHI$BD$JkFi60@bA2b(l?WYYW6vpyR1v+gBgU{$ob%Vu9v zo%PDH#>7CA``Rr-Y5p%r3|lmj!Fdh;9dI|Fvb`9bJ$xi(iT?R4M+PLZW>7`n=}y&)!s z7|RJ|!+d`m5evMCFv$rdr!J`;k%&TK^UFTmouMfC=18HCk-^qnD+Fb|zo7ie|1M#3 zWb=U(7J-~r3V10oq&3-m*SvQC=lMf0(*0m40s11*R&_f&S|I)Ik6FNLpQ=Uv)r+Xt z6}l=uZyiUqx%uRPA~DNnhB{9UX7>SH^47cYKczFX=&^UnF1tkom$MErZ=9eL9O-s@_^ z7OVWbHDB(Ig1y+PwT;NElaf}=%0n0!n9WuW5QrqeZ5>LU{2j6-s+G&PqbANrDeSz=eMJ_hHp>U%$vgj0;#Z<0FPE7mywC z7V=_-3brJ=^9MrJM35kuL@tD0T2Kfc^#$>lCAAI?jf$ii5!r4sxF8`J2TAO9T;I0< z7d!5QY5*XLt&nBz31oR&*#ppV2d=!dl!nX;_VShSSl&!R<(|*}V4-YS0#LVc_Z8hb z&}O#QW{Rb?ktyxqGp-?nyvKD|y%FX{m2`kfy2L3hkFze;1AWzaGZH>ufB!vS2aq7p zr`~{f_EZgvmjN3OhdLX*idIMnm7#DLYEo2^=RZRG{vsfNB0$i$=2fGCz&=kbEMh@H z?3UsJFl^XtQ~+$yLlq$!v9}0m2^^Q+VG^2$;1sAqdz34YNP;!MuhDi|=otISYm9Zz2GWMHcjw$b;ye>l^1 zxSDDYQ`I;ROe`{rOcXOUIZsp_Y%w{zHJ$8labN0FmUk*%dgHL~eALcQuPVZqcR|yk@crM7xhLGMy6P_`?gas9ApX>`+X({IE9Bj;=cNH-k`g!AyBf+Ay@XAa z@|`F^!A2`kP+(Y15<6aSDK3s&d+8cjqyt$nXi6B5#|<=_`Gh-go=%ZxMj>?Jy2%Fo znd;M8-0bE09`tlLlKG!{~ZF8S-Vry7GMz- z?d(eZrq2AqWSCbEWh0G4@xxHqSz|L0M#E2q|8m{ErT`%0#6qcVP8O3XSaWE^MDH%l zSl0*9XNCfsIk;vlX3WUyt@NO%4W&^6#R6h9NxqvKZ*){qK~lY#<)QGPHu9Ye5Vi_o z8zt35x{1ESi|O`QWgD1aG^I-xTdvo(@$K!!#=W)g8qSU}E*O)WxoBggeW7dT_%};7 zT`j{AT+7}&_0skSQ3lz45mx)tr$-v>u1vJCkCmQBk-=;~(Ot@MzqH}un7^0fJG(q) zrA;;ZNlz(RH$k^^xYKJm!yerLPsC69i^x=eZswOPLZYtse>S&fG1(Y2+SwN#r4VSn zql-x$z(VK6wEAvThK(d6GqAU(cZO6n}14+3vuBOI@&v<#?uGs z8#)Xc-E@NK(3kzv4F9>}7cWHd_`7H7*eKqOyrgUCla zlNm3ZFKwojKW{eeFRu&4%A6hSXri#$3e0bwZfDlcn697Vl|)JeQ(B_`9c(~lI6M0_ ztM>-E>fm&vaW^ksoF=zJ&oLK)|F{4pw)6gw>P5191^*}ogg`39qx)0SOS+HR`heYP zEpNvOb{5ewfJc~E?;lGZ*mPOd7l)H+H?jdUpT!;fkM?);E`Y^KwuQg*3&r~o8e-A0 zF*p!tzF?W#zoZXN9H+-1>tLc8FzTZXH;lqG)vT^)4x?}D%4fg>d5T3%0PEBa4XXRJ znQtn3Rp%Pq{~(t}1xo0ni*6sDjmqBb4lSl^xkUNKS)m1raCez&hrh_^;oO`n-$JiF za_8!t5)Oa7t?%sNp1)h?NPX~W+beUluxY&E`gHq~5X0niH_zAyDrcuy}nJ8p3~&wd=vSq>H2!5O3kMbu3_gdWlf|Sn^@GCP6eEhX~b0dep~Hh zzSa2zg2h3jyztFOb8%rn5aj(O8X7E|6r}nYToV|IRGmbt5mZX>h$TmQ5L1Xk&wG;V zEjTqSAPRc;I#|gDj6#4x(aD&ma&|gyY@htY4K+Ol86sFo2Fwy`otLWdHnf3?3PxoT z7Jwq(C-{DPT$CRim_CS8P6o@6E(B@Wz|tW2tgpus?C@26oquXf-Oc>{)CWCodzNx^PhlB+csiLuRg9UH??%^?0;)i+|0kf_FBR45Jx`*)l_T6wUQ75}%3J%;8_ z@nE)6^-tQ;u}k{Or2>i6(J&ciXbhFPj1AY3E)#<-`uidJh!Mr{?E?{J?*FF0dOU1* zdmP|#eJ|bl(z;K;7zJo4TkbA{hYbBf?W)3Y+fnp0=sp->!Y-7yr=uCtG>4 z+hRbiY|joe1EjJfpD_`o_w@~jMQVPs$X0E>EbY8qcI}Wm^(;aij=yF)m zo8mH>-oqmZ$g?UoQ7qCzyoNr$*?n)Wce3o4`PykHHEsica7UKXp+Q$AW18c!)ucs% zt0*}^rHk)mpjZI8p-h59Z=wURm%;Igcr~AVu1}0|_M!xbo-*WR z#xQDD$VY%9epAmlN1Am$$LoI_(F@LE0qJN>W*#HVI)a#FD+qy89vzvz|B76q^6ee< zO$aP(q`HYhs+A!StsD>6$~I-{zzg|02FWaiX-+|_3d_M)U8y{CSFW_Pdk9?#`7PLD z;EaL(l#0^W!R4lPU737arCz})S4rZPO2U+F6d-=1;?-xSJh2TTZMfIkYU-c+2o?)lKJh% zm5T`He(Bs4Z%NL-T(nOd&t!C4zsk~f+dB=1uOtXdvKp>*ku5@8^Uj!7#9C}wtJH{F z#CSqBvL|G#{Lypn>T&UKa+`7R%8DmRn@mFrBTKNK4n|D~4;~h3TXi-!_2hY^6Qe9X zR{wdP&VN9{tk4&={QB=N!1EHyJC%vPl@{l}CM}^Jl0eLJGU%Pduz5FMv)c?1gVj!?DQ@pzZ6~WWw?6ZbX$gD>Ee+NuHIX+A*PSu1=0*Skt(-Wr}P*K@D zoF6}24l}kO5%W^v@TTGEGAkG3ntTQV*83@7yAtq{m}$+>SX!M^4ImbefbwUPeCm-^ z0X!ik8}KyS2Ji&ORP#*NO<(y9)rdO0!tdgC?~clel22A={x3M*#Wy2$2+hF-cEq0F zyh(PlxF{#8I&Uczb7^h+uJt`v%$R^avHIw~Kkaknzw5`V#|Foz9-er%f-#hf+qH1* zI}@mrtlI67ad5$x=Pz0`wQ00dSI(T(O36&t*Am$F7#0$rD6vz(pq+Zm7}2RtI8Wus zGfzvnLL>fb5!=i{iGY~fprgs94*(wZ^pu3 zt*csweVDy`c=($^he75m(U;NhZ%N;<1hOH}=%?sdp@Eji*h)0p*$F{?QN^Mx^ai+U zdYuI7fbVI;dQxNQd9}ZFn27CgSZKV8pkSHE{8`*K@Hqb1@q9`(+~J;d4~23*8&cXq zS1nT&`zhuV$3fyvjk|rvF2hqSls{D?$}dyhSMVOHZU+62eY%CBJU2_I?MK`4je@^m zW~h{l3{O;k`T7_OK~vSqzw>_qf^G-w69s}~m42EA0PorB96xn-m;0-5P)=fzg1kmX zP)-EWH>5sQ+jW~yS~?nSHA-eGOgm-J*?pNDwrpHDCn_)t_dy)w<*1!jp#8z6*6{DT ztMq!LFIM>RX#a5+djrbdVRzhph0A6(9h#t!r4>^=VHguaXc)FWstLL&#N<6iSXcf} zfcN*gFj(mRpI(-LV`_UQzlHV@1j(TV{Clng91xjr`rC<#1!n16>9 zTyWp7k453jMa74*XxMspQj~F$+@@G&4JPyRs>KWCIs+p?6jN8^1g9;or#EG(_wu6K zzb3qP$iekl;WE3y$RAT2emB{V`*3r(7v>l{EAaqj65S^+Q-PT-=ndHAdixfNUxw zrFu>#F;)gH$08rJ*sOH%d3Aqx<4CUusg(Sc$fu-9`G%55E^b>*R^AtRt{#RK&k^>M45gtgNbitn>#FLl8lK27ApY#ZU|aMwUX_ z=NL>a>WzEdCe0eh^@b_9i7sg!Hv0y(`OXKsoVELU8+ROGzqs#hpBn_ z4JiF|Rr82%U-h4Ibv53#lP!_t zGfI!O^~;9vN;jb8$X~OB(iv#F`kLP&jPmTjAO|O?=tSW=c%nkQKrmj}0|u)@a`8A~ zSA5c@i8gDUvlb1ze~^pH%+C`udw!mD+)o&4bKbRO&ATYnSxlbc+mk3MT3B%UMA4%A}x>=ws1z*X)0p5DG+aP)AfkO1_V}f54{U+@ZEOW z7vB6E4weqGt*<>1u~(B3e-I;jk|V53MFg=5M^)%`N8U9SQ3cdmntmMLpP0~?EK;p5 z)oL)=E7{nvi`9=iGZR)Mr;v{Zrhb4U0zPcL9HO*>|09p)c)d9~;2 z?b8;?Ym6XgvZ-7X7mQTbpT#l#rOep-JIl=09if1-9L|g3k}8UV1V?Y z_>ak!26bLp<576m{ZEfma@<^!!j@jyUpB)|MIWVM5hfv-?9i>&92u{d@C6B&*W^rU zPCpCLGVr_!kUSBx;AG!nHPdN|X3qzWu#idF_%?k6L&-@?1ZedQdAQ4vUUc<{Po52V z_7`2?PklRRs^x2PX-jc$oBARkq)NHq;qh;6^sY>H#wUN6RSL8;=@2TW|BA)^W~Pg% zX{}bZs`#7^cn`boL-zQp^3~?@;dc+m6Mi?I!(g@Ij{LjMk0dgpcM?9bNQy|1nz=IP zB?YQOezE%ojxIs4EQ|!L@9q)*8%6Jl7$lxXAzw@o!UC3l8pwOFj8@7foq(Qi76Q#u z;YvHHz!_u^o0JdRlUU0%w$Q9z%h2HWaC~S>a<=!Mfw6ZB)h}zbyP74^as}2HFMu?srKqZ&y2#fzNZK2_`@cU6bP8l#9 zM99`(+b&R-MB?N4%fj_B8mM^P5Hd_yTXeb|3oKyF0y-hZ_Iaer?-II+rhCM&o*-Rf z@gKN6v%T57QWCV1&O)g>;?`nA^`#85gw97tK55$1<%QS8HPku95ou`;6Ah~OoGEx8 zL8DT{D#d0{&ZU8ZGvEv%&6bfOC2;{{@oADQ}yclcuj8r!xtb>MHLD zO$%Q$wx&?tC#0}<%pnQnz-u6|TU>pC$ll0?#dm3V0-q-map@DFGF zg2Vx4vg)50(<17M;e4}ml(M6-B(Zn6YUgcs(8K5Ni;5aJ`Zy99-mh#G9U$NSn_4@N zGAKh}dQJA3!Yq+&b+kZ6olbU!mjExV@$BNf%;|3#0M}{=Pp;X3NnS9?cUhz=b9*IZ z@j;hWHJ5=zCJHY4TD1>B9=C9!#aV!i3c)(r^;Hi;&|k#N(@UZt8i5@HaH{4z1=YaZ zzy=Hh^cX?*S6(1ukYaELKM(R&KHWs-XgOa3WE9w&34XXaFqn zsU`@4`PnhYvGi*}g65f#+APaT5ic1CQu=?{&s5T{O%ZxR$wA~lQcrz#iw|bbfe}pH z);lXZ^|d!L2Ekow``bsoi}(2tp%J@X-Vou|z-zPQB7v_#ntKS+Hyk|oV+@OG-Ig*y z(dU)tQy5K-S*`b^-R&Ht;kohal7A8LPTwudfEZG^=lr39@hy6zh?jrOl_%5uVhvMr z`)xhR?~Hh~DhrW+-D{+Fex^ac3`uGg3NndM<%khTQSfO_j2St$Fp(6*rO`m*2;^Yt z9(yx1XSc~3syF-(mrHS6vkgV&o(u}cE~}v@Ku<<%?dbUjqo9sNzXN^S;jtTh3RU%Q zSzCuS8>#ab4b)OC&OofoTdh96r&h-sJbmar;^(_Rx*)Jl>RTTPXiXso926TflU0cU zbjhK)@fY#-!YXX2K+*FUM1j$I0p`L5p^Cr*9-yvz*c{mK0^*9Uyfns-ntLvQYOJyG z>NClXK9y!k4C#>2OU$%;@|fssX;h8HrmKC8ROjPEnwjJ({_3oL@LDy zrUFYfEu%Pi@2V1*sO4`nReKe3+99bZkhsdGXTd;pZ2_xh+WBn<|1#8Nmw$tb>IGu` zq4C3hq4Ky;?#E{V+7g%_Rwj86sDx|;X*$8q#k@_g;>Es;^U5}XyM|8iU+DJkcP~}h z)28>4b-qyQ*Koa<$bR>B@+d7WnAx$ojcg^egwqciH!EogO96-bB830n> zy>UN8>ADYBbn8MlAT=NlN_*{K^8aH^3{p0Kqo8I(J`Dk2z!5?;Wr^*(4gJnN%?ZU) z6)2QAh{KxJ$)8T4#xNt&RK?u=_%K*@?#$G6FgJ(7JoN7PcJc0bxt7I`864E1?(HjW z<9q)?fk<>s{*M-S+C%&OqUn2$+a4U?sV(R^@GFmO7i+^G7A;fmu)IY2LSWuv30_wB zAJQT78B4_bGgaS@bGWa9z1UIHvo$wgdV0cxiCa&9N6`tHyqpD|y?gtGN!Wc9Xik6@?#w)+PPTdnd=RKQR+L*Mp0M{rPji+(l4gZ#1Jh-`c ztU*CVCJTdb0a)5&8Oc-?`_8Est(R!(Y6oTiQepn47nl!69rjr4)$)jqa@xykxf{Om zh_F#$CZiPk%Q1Fd^oEUI$u3?UbZGf+jOO>sxX>1&JrqPLg~C&(S@jNtFpm3e1DJK! z+UNHzbwuW~y3-&nboV(gB)(1SB6YZHagB{*A-8R)e zTyD4Hj2f}~A~<~he}8Swr`Ummh3MM`E-m< z=-=*jJLd}GU&WdU5!tRn`2EW0Q;& z0|)e6bKfQ7{}c@Z>e#r8UuG~P;8dLiD_dNA2yoF zO06!fx{3=gjkK$|td{ELsJ7gk)z-^$qO|LiS6{pE%RF^DfytO5?-CJO^voDd1E=O^ zQ(X)m4!Zg%TdV;P3hjyjZi~x1D87b1{A+r+?X7%ZGo)BKqC~wt?L4@}5ls7WgAt9O zxTD>a4iGz+(mgk)=q7rr&f1?s3115kf+G}^DUHI@`26M7%WVRg*g#%Y=bF~|pZ+@f z6`QW{bKmCWp zT4ts_UN>H`B~Fm12~+5YHd}T~)}HcS$axX!|9SzE2r<@vbZl+jVaxf`fMriA0KZ!$r`~v5+B}v&Ej=iF|xw;bZvz)yzaH zx2YYVpc`I(c)XFS5lbQ9yHBaT-_%>g`|fBeg)Q(J?OMPjahk&x9j85QlDuYqYV!@h+oIEpY+s;At~%vtgoY~atV&4&)d&q1rWZEA ziIj@eI%h?^q1%Y}*M%2W+GPrF(i^}b6#ODCN?kAd=^l7u8>s~-LkvE)3qBBI37eQ8 z2&dYn=$B}PAKcVlm|YcXa{|XR^?D-H;Q4U=>m*g#`wq1VZR|e_QL_hqd~=*nCj+Gr8d94uXm@sVyAz_g7emx%0mzj7;`{Qxd_WB*nf!GfD2!s`mi% zuOX#Y@It*1z|<18%CYa2!;`a*qpi8sRm_0dx+?*nc`6Rda~)s(6dqJG`Czwx`fump z>`sStR#ZL9_~kXh4&C-B+k4rD?6rwhAAqm=&3Oav9_c`f>^Yf&Q=5q@Y{aHukcxnZ`TsG1_{B0hpC~4mLsG&SiB9Qc^i+MY_$4!2u_G z0ZjVA%4#Sn?As6MY%%6~3xCCpw`jO^Yj$VtC&}PF);3FkK^w6!8mHOkzy={F=gUyV zkNlErFMmTpx?lRr%HE)+*8edAQIx0^ul?&Z+@HPcD2=sqCjhj6DZw+2A%8MmjzRah zp9xs3N-?7!CjSk}zf)E7v~hk2;%sI0EkIUkN-t0xnuh7kW!M^{*#v^?J@4GD^&ebR z7*wwy##389_^V=NF_#)LUQxP9GA8H`FN(#SEjJ`IPMXNl4V>Jm>iY@Vxs#l>TAs#= zCitn$4Y8ZH`#9Ot2P2(h+Zo)CXswV;61pUBg!5fw8PhFVL*<)X(R0_c-<^gbo(`#x z*SsaqXh6g1zNG!IbHtC2-=dRfFlUrlHg=HAcUmX=hzCIZZ|OQuM!-bEH!PWWlM+xa zuNKia_#u8$0j92N0fKRSz{YXm*yH# z);rj3zDbz%@VE;CI(#1O3-@ea=8xSri%uJ|3oVE5BSc2u%H8mr-lU8Ma33Km669in zVA<&F{vu*30}>mC_@6FJ;0NCJTcpv@z)D3h(&VwGsCsOL^=H0~nOMpKHW(11{2I<% zT5D2;RJ!h=B$d4n*8jGsP?~?%7_$8A2zwc6D2vkM{^c;{Pj_%44|tSy{hevhtyHmU zHgeR20(VJy7gQV?^9WWZLf$tf#PNzOEov|#s?zOc@8kFIR2=<-G*uxBL z-O)+-6+Gqw&H{>52)0$QdmH!}KL5ve)t-H~Pie##3`+lNT@`gv+*pNFW9~&SCY6v!&K&ie*9s z7J}Z5C{_sE)`mvnk5uWdEo9AVbNyWE1~EL^74O-u%7*X@w+q}J_6CP}pz>chWuG=2 zWQg{CDKzc=9)re{xnhu1l;26n{%nJVd~^PN1?3S&{Et!WYlU4VsHq|($7RN-m;T)v3WTghYuF_W#Cy7l$*k2i!j;{nahhP`{gF>4#+ zuK)G)mZbs91Dt;kJCXFoi|M#=jE7zNT10R4ORhQ2Xf4d$Y^IhGPT#jS@&abXeD!Qr zCrj=a1JVU zI;x+-t>gRuE=8#V7C%g1%!p+WRevN!P1*=r5hLX**%5)J8YYylYc*Z){JN1$;<7y1 z(E-R+?KvY9VM=bi+!pn?>aAQXZ`2H)1{Nkxxf=`osw}V?C+US#VhkEXgx%ZzpRdyT zTE24D1GUPCfrHV4=GlIpCA6b7`d)^@)L?PNl?ot~+NC_i06Kb?5&lbs^fUsMhR ztVR?m>$w=fy6&aJ^Nks_lqa;sM13;vJTcFp)4_2s00`j$BUsW>@tMony^jV)0}QO^ z#UUOn8Xk1H!(=)?3UP*i_}CUK+iIQ34}7T32u)?KDD+n$60UXP>2W`pH}wq@!=>X=HanE-WN z6**Mt-~aL6-vy)i&ot($S12tCf_#V}L{un^O||Dy7OV3sj_RkDQ#Y0t0tLd7{9bSU ztiZ8x0$vppZKyESKgbG5b=it2t93YR7+_RT=)Uh(JUDZ^@M%`9ocN{E!z2y2qU?@$ z$!m_Azm%jvPEa;PsQqm+Y>>Zdr?>xzz2yy{b%Rl#G6oA)1x|k66BK^;gEEo#aZ)V0 zfsrmjH>nK)ybehJ1KOZ58Zqhb)Q`a?@n5jvcrKrQ`3)Qo4EtxirbtV)KDO#ORr#jtbG_TdIA3ukcSdO66lz$enacC6;(%&HG<@1Z z0own|mZIgW0!556p zh1Fzz@$sMbR~=}H_ID{Y?WT^Q$Rw@b#b85G6cpb{9KJ0kQ&aXkG(RCq_|oUA)@bww zQJ{`CEzW+yhJNeAj2(}$sa7MeB6C!xj;M=z^>T%5KM|*K3BGYHn;rg?+v&86$KLOn ztRu(jhJ(r-2|6eJUsh8V?47R<%yRI! z9Sp>&RGnTwQiaCY6IIx^DU958CwRE-HSrU5e-2H^C0Pc!bHadpd8Lt52`YG?XM&S-?jP%gyX@Z+oj@n~)w9gd&Nek-8BHEnMV zb%kYei0wF_>06X{QN46QG(u@eI2jRCnQY)0!5@ie@}yJ<^)WiiYu=|o4o)i5_1+3zHwgROL09JAh;}lV6j+tVOVNZ}R71ddI7YR9x9q>qpu9bG z#u7nP&vU##J)D+?b1gj3O)TE3CZ%+xKmIfA;$z8L#5W{nFHir6l0Pu% z<@{%%NpF2&WhLgPN1TjiUpZK~n&|J~J^_d1>u2B~RUZvdbw6&qcsQLqgwKUx&T_iH zw%X8MDr}2|H!)i6He?g%f~Th|M^K~^@>~|S0w)4{BG7t{kDVsp85R9AmURl^ktLJ= zHmrE`Mw%rlc|&-jv8=_rk-g|%U)kL!`u+{sA9X zDS;#LRi__u?yKbNFfkjdF)WxmS3#-XD^gXZnXv*Wqpwh}gUe-xD{h^$ zVeeqp>~Rz9V1ASQ$@MEd0M{I(&qSC#aDI0iqqxY$eOSNt>6?^J=uU`WnvI_^g5qOH z;<^rek{)6J(GNvr*>fwK5At|>^!~s=&h#TT z^_M@X9bT;W9MF|@lEIRL`i?SSqsY`q=Mxtu#jRj0G#@ri%HFN~ zUKOXXqmRuekoH9dbdgiKe`lI~>?PT$jUlx+ zr#OK#3|MSty0zCn&N}Mz#00uth1zu-OoPk>+);$^#lvc(1I@SV_EP)P>h$kcn3p^_ zcmXR*5Fd1G1CZ|g{zrB5-`lDxCH!3o$ z>NRSM&E#+y&&}e&oYfFhE0Orbht%_TVTAn5hb!R$VfrP1l9PfF+aQ$QmdV^pgBIO($%sD=DAQ;+_O2ogHV=w{llS~vu$;ANnnL17txhcZqx?+E9 zH?vuKI((9#dK!-F%^e+M+O~@es|}*uD|4ha>UYjaZl##HB#-qUbG08V|2zKgF=OW) zF_0MeC4|Jpnr9^SSd$_~g^;tx)|`g71Q7}cj1%vs&Bdu?41yJwSwm5FwKZ3uI*#`7 zHErM^tlNu9`*m}&<6L`H{qqG$3`;zphyJaP~3GyDv+O~wT0AE zruB7vtz>K~W2KAnwm0F=*RZI_L=Xujnqc5^hlV?_Y0_vs9MzMGXBt zcGCl6Jdz0d!Ac`slf|Q27Yld{PY#B$w0Z_5o0~2H=B zN+7~oOH#*da)P`0wEci^;qC|1l|kPmrhq{1;2V5y=G&f}rHhJl-)tTzy+89?HP?ab zP&FakGY!E=svLCLs@)y8%|BXh6 zLpl=g64l5kPCkAtu%Wv4u(sdr*R<%1z=XvWkxFOA5M}&yc3Ub(9&;)cShBrvJ#=2S zJ9`;e_xqp=xKT7aT6uE)SM6uTbm&xr$b@(@TG%q$go(d4jqzX*{XkGiAlq`@52|lK zYQ{EZLy4pLJG5_M;w5TO1S%{nnsLE*a_WMZF$EJEaY<`}oa|#wGz8or2VGi!DX7wM zOiW{TLA3>q+V)$c40KjfyTZGzZJsq+3T|$dd6$1%hGDL{UCy5ctwSNhM(bZZwlyDs zy^Ep?1cRTCt6oL=dI`3#Yw}_p!s`wr-RyV=R@uJ|swU8|oV^^&U`W%9-8?mYEHNoQ zqtC0ZbL*@vucNV!=2gEUbRtdM`@ctKf-ltRumMlzyXn$3|HQ@Y)ZOK@qe?YcKKt6D znR(bmbBTP&aD10TQa$#sx_t)4@@|)4Cr!Q5dgJyCNaHPNpMzl-BiVIyuHd-vt3G4}X3?K77t#Mx8%#Q;Lln~z>Sv_k zP>qE?n#x9<{yh;BU#pXFA!jp|&i1S#l?ID}(qX+q`D`$->S$~( zlE{I+K?&8~ zlug0G<>yZ&qF$wXRjAWY=N&iN>C)At(0nvji<8T;L(M3Ug|OgalLrF=vID8 z3PTtW3fA=8nG$d$Fhr!PId<;^+~iFK|6sQBi5+gv8SGx=7`Y&KDGCy>VZ~-6~`} z7FraxmDYw2|BN=Kr8=p(q<&22INNt$zh~rkys4y%wd-H}Lu#d0%I|c&{I5ZkN;Y)$ zU5>R+skI*nGH_eA|RkVfRti@bc#wz2_lVjcXvvM zfQTrKw1701?rsDGB&EAV>F$Q#y83zliFbU@aNrf>-hK97Ypyxx+UJ~1D)V}~@zvT& ze&@9~+8XYW6Lw@rX#8)RJxI$$!d)Ul5gidVkY0ws(2d` zI~CKib+XnBlg%q$-BU3+=iOYgk-uZGhXcMcJj~ekbPM3UN( zf?Q@IuI_L|sj|>(b@_0qc7pToxf!7RLmJ6Qd8%6o$zC_~JD9fXzeg_zXD{xxJHp1E zyGi8TOoFJ%<9`rTybL_J1-GK!o@7dUQ>3ioYWny}Ke1V5yAq_ujNtBZ6{2U3^6{(O zpa??^; zig5BMhZy$4sruC){nI*QMRtWc(EWVM5omJ&#VLqc{G&HYhTP6c!N@~|fQ1ouj@yeM zYOer0&K+N$Jp}8cxpit^Bg%VE$(A$=?id>H+)-gRd|9kL0o(Jx%f zIuu$Oadak|I^VBQa*oAFdJZY-qt^0A1c+8$`{Kr zf8#nl^*z(gBY7zMPUXqExzXf)T;%xs-9o*^s-Ie$iX~Nfk;)TMzR?*YqW|$-t%tE# z&e}2-)nxTg>CP_uOJ)-obOg4<2C7+TG8o-?hsWA4WY1t0=k~0Zl|J&cBy(VC(lInC za+mN28cjuE_14^?%$Aycs2SCH986a+!(W97!;>nGE*P1~?LC>-Xgi70p}j_t!iAHf zkU8)P)hf07JbQ5Jy*cZf)%r_@*CYgC3&a8~6*y;&r`=aBN0;q6gr&MvE@>T%CLd>y zUH;_%`h%#8amWk0eTU@Dqac@Vfvkp%?4~9HHeLN4S4TciCvkHbdd`o`lkQtpHb*4R zh1`ai|G^E8f`tF}vY$G=dMc!^bo9}?<0hKJv@$n)GcUe8`N82?rnFIx79Xd~>K_J` z+TNU~dt~)z)iDn*-6SR5qn>dT)iqP&}UuuUS^0eV~e@Q>OM}>X6If!=RJ^xj9 zK~Pp)4XyU%oPSxgy!+Eqv-Z`N8=PLoSF2||su4OQ5J~^rc)0#iKdx<2sdk2I&meX6 z$gT$Cyf8n$y_v}&2QgAG^5h7+wmP4PN9Q%4gbytuN>RG`_5GT?!KC`FQJd*EgsQee zug1I5viB%g0)09{Z-krB?zN!FU%UI^9R;xrnoOL;a00$kmU}gUX5gHEdN`@!ls;T6$zi^0QMFn1-@y=L{*`uP!N%=17j#0)`wMYdzeA*dq1V2(NgOiUw2DVzP{^!C zXOHF~y3&>W6j|%IaVf)pyzt5TjF80|`-fe)N5s+%`OMSsOd5F=+PtP9cA9TO0z%$& z^W@*Mj-2LLXUjxrc%yy>Zxb&|%czUvrVA7sEm%2QdMrlI+?ddC{}(5C|BDm0+?tB~ zwW%RaCppbVi#62zhuELFeTgX;2bJC+L5^O@sc^!^!>bUIA7H&*n zT52a&3|8-S5s-a-@b>rapHH<9h_3&CdjYs;7gSw8Szed*Q+>@wi9*qf!8KIG>1px( zG~JxEI6UXlQ3j2woH1(DkOMkzzvrT5HZ;ymDMsc;kvZ@Ck5N0Nsa4wjj&`inB7I?T zr`SzesxUt8WN`iZOA>*oQDMo194ia!bVUy@ym#-!CI{H@kF4u|`+o9Vnwd;`_CZdr z69om^iNPo|D7`>4@$J#-kL+LT!ZKWmPH1K*k8YKsPc8;pt^PESV51<<=}Tr~oFI`% zC!#|b+UHq0Z^49J{<&nw-R47vG4uVuzDMyrDW>SL+MQlb{?o+Y)y+XCQ7qT0Lh=78<#fbC+l zVTDeZh@z0`J3qZ!!e0UxqrcnHntq#_Ya+m>UocG`5jv}wd3DCYS7LDxHu8M76uH^6 z`G4j2+Qziq(Z|gV+Jc4$oGOZ5gJo-(#)^stSOafwMm1+j@1?)?!$f(swT2c&GATixcN?#~JRNyG*uzW(YhEnH?$vdF@kp=B7`d^hG(7fW>gSEgz9HI04{ybdrfeB{ z`9u>ee4etiCX$CI2_BRGsYK6E-8VDI>(Ark4sRIX^h9oyF&KY@cz_;4#f*s_hl+EH z0LzyyfwEiqExVmE!Ywl*lijra+i^fedF|+Z?y`f@wdgJDb$nzYdH+wh)aqUQzUQ^8 zGJA!K^3kl#C-0UzX1TUmq({vkpX%X3GL;~Dvuu95oa3=0bougjIde(z`W*W~+D+G; z6?g4*)3qF?nqs25DVI~|`sgyb>oM`LB{n>dY_P0VBSiJXV^0=fLlbFiD=L^v?=P10 zY47o4i+PuRD7Nw;c3HdFU^Xtzos+kyz#vA43_!C&_J8ZBn&@zO)OguhYvM^7*ovl| z)U}q}JCxnvE3NdRiCo%Fdlha%+HBN#1==pbm^ZJzJ57_QBbkV^9fn>$t7oOY&N-eB<9Jnam>NRuQwA#5>LJy4bvY=F?Fc(#e&$ zQALaukU}rSr1u@=_PcjVlmyt3=}hG2fA|u0Up6Ms6BL~~45(KRP;aZxcX1XroGovX z9PZEf{3zUp9V5)xb)87ltG4N)MdtF4jrPfPDQ;u7li|mavNsbJqqVzWqFyB0R7Uv9|azL zz<=z5rN9%qY(N^vO~mf0pS`jo6em{O8Q4CrWo5zX^q|V%H-U!xe_Dk{*vM$gnZLq- zXJiIV&n4EKwWbt@dfA@aptnVTziYNrR%3`YxPD_nGO`mpaOLH&gXtv^80VPdw_N0Y#^QTA&v-6HXD^*?5>7`yj0cTUI%4mSI4+Q(X|E|Bs{SdLe&XCu zsK{`_Q1-jV)bBb^sOQSgmG#d>o?Jzir!~4uuxUc{*%Ah;NA~`38EafQE4s;m6SgTP z6(OAfd2cnNLfU-X$6MFlxzVsMGREf0y<(@&=f&xpDAR9W<-yH!*MD`?u)tjJ>G5|| ze>Kxht{OdDPGW@au%>F?A{rKa?7(oP+aynmx*-u-)?hWM1)hJfkNd+sCY`V8 zc6QRwOlVnscN{!jo=Jb(fyIQrQQ_gFrpLo<&PRikNl?H+6|EP?VA)V_2OXC%p4*!nTtMB^8 z&4qPMt5OM_wH}XyaxYNZkFa^NDzqpTYP8!+dTF=ZE>|cUXKL-Vj7H~wxs4d=J=eOE z*d3a_=hJa6Ht|q$@nhSbPhyGObyR#)6mLI2{ZsX7*=%?UTA&3fTV}yioHPB!IFkaJ z{3eCCxbBQiqkEM{4`)U^Yz=;1R(ubbkU}n`{&%G954LW{ANi~8HZrdzlB-txuR^KS zr|x4cUj(uhB7LP%yeTsoLVNjd3P_BG^)knAzWuc`TW_-UyXc2$-vDEfF-F@n5?cFL zKG~A=?mz5G&}r3d2V7|>(WDWQx|mGbw4eOS3$XHz==;AUXFPh9G0dL#ROhFr{m0wy zMhZ}$m4(D^OpeSH+ibLG)Y@#RS2VcsBcXNqf9n|J>9B5dbvn#{Kd!3pzK*eWOW=C5 zh_r2wd}e?Q5x;CY@8|&OL!R@gn8b53H=e?)lg6Qf$Pn5M|JPRnm(9n2hI2b22x2em zI?YxjR@^$ng)$(n1izr-JksTUj`bxGjVU)YNXSvE0kR8vT-y7tzTbk*M+Gxj}66ch$vCA#2-b zvq=?gd(y<-gyQ+^-a=3Ce81F76udtEM&c^c>drGCdC|1qmNP#J|a^wJy>}#iwi~eswhh*ibjf@9mTY`uH3@l zs3AY$28ZKxMamj+qcS9erT@SFLG5_G=WdeMWs`GglGk(x$!+8NLFkQ%nb)!h--Z!% z=i|h1rzj7ENp}Z%ZC)07ZvOI`>>rRTFMgbkuzO~0PBETT_KDX1ddE~>I=dy0>tv6* z^~i2Xbc`qk8rmZ~wD)+Z?*c5o6eY&n`pQTOaw=js_LGvb-#}R&08wea*Jzdyds5bW^uF!=8#$ZpXlf0L2Lx3(axSOf3o>{+%y~(80XMz3fuVf zQ%W*VbUcS75-8w49m=wMax&EgW$r4L$2}%jqi49h8nyIz!V>g96)G~<9rT!D$zp%t zgql32&2MVxu%9TUrq9+w+|Q;G$G!C`8LxHnNy;^pckG)@glubB6t>dx3=%)@hgE1m zM83|o(B3Evc;_c(u@J^wX6;{SX|Xv|f4ZGwm84dxU+X=pFZT$Uzz_Z<%Tp8-QKDX) zhx|^fqO^}22RYx4ys@Gf#G^sQmK&vaRlT|@5CdneWdCAy6V0*6!kl^ppHHE?%sU_QQSv=KOsNatMQXa%xr=WHxmW( z90hSgoHPg?B-I@SCRJ})Smk%+M$<1CZ=~lxTX|bDmw_!!V?uq?I%6*VrZtTT0^2%g zF1=Km^c(e)cPO9V`31zHQJ_-jn|)K<`juD6FONZpFbNTx%un%7TfHZeo-W^vf=Z~H zr`_Oa|8qlw$3|n;L(*iDyU`k=c3tFOy=%*{<+XU?y4e!Q@3FPZ=+Q#5=lj)4G7=+> z=C*X>`)}b_qW#-L*`4aN47s#Yr4P_r(co#pihK{&wB6>9$QmvNF$Eb+sN4~Ai*~+p zUA>`3XPOC83$!<_I}a=oU*E?cMJ_P3AM6%H3MQin!6j+ZzT&9p0^$Q`djW2k*OGe| zO;=qK+_hP8tczEb|j{@{jg;3GL@3MZt!>p+;cWrOGxTkCt#}q`% zdR>h+y9|SwntmX?V?>=Efkl|=O((QtUX{&H$SGT+Mt9*X@TjY6c=#6HQxv$0QZ#)7 z2^`dmcg5jx;uZ_$H`pFamN}Q@k570^HsFL>ZB(;cR}5Lhj-obe;(uAm^f{f~uHb6J z-eBu6IO(pqb~lN90V*@Pgp{Evj!+z?xS5myT6%U>vRLjo$vr>&t>W}0Ym$)6fi_jz4JGz+HFet83T*DM1 zf0S-vAsdGoSWQTtDuCimBR$>DV_1Zr!TZ{Z{oqhk%nQ(k$g{Sb-IfqVv72%rj_sX% zI?lI>3?++bn-#TUGyA0nlWzYpTd2u-U?VeC;h!`$_;t(Z@qfVyeEgS9h!p2ftTCED z2QY=G%Dg{FP{Kn7gbeRAM|_~JzD?gJ5tGn9+W9rPN(}3R0A6X7;5$5h8f<~VZOQ+N{S+E z$w=flILu~C_>KlA-H-4Qscsp&v-N6?qrwq$?nGt&#?)~C&<5u_Wc1wqU-Zzi{ZO=i z%jUYW-^U{T-=!r57kSeT?+sr(3YtDVI?Qi)Vgjt0S2Zq-8{Z0FprMjJFKximU5u+) z31d6Jy{3RayiaSgIjVSCXePJkx16o;qv7)c(dtI%=gSY)Sq$e+OG@o*s1*57`S{pw zW8vFat&R=YFNF*{7wS~o8||Gg3gyn;LMCFyKg*+Sb-{H;?C{*5u`p@{C%#-&k zw->uBT#3;X@!unJc??q24+8zmntIB8P1m||e$92re6Qe2wXXlTV%B;Te|-QY8Q(y+ zqWmyVqu2^|Y4bgZcbnimsIXxV8he}em%Xt3^=O_}6!DrZZ5R$DKIgYRKOf`q_?@}y zBoSs;j)VQWh3$hsd1@WmRGpv@Q4?bqbLHRUIEFEpgN`nXE~y=&5I{%+s#UWgp>~C5M;{8V>%urwy(-3#e0c zGG*dqi>_vitb6{o2L6D0@E2pmy@m1&U8M0s!7pPjY5^(}mf(W{H95B&hDq))jC}Fy zbmZQCKqROMrIBdH{%FELc;@u{+*fSn|>;Lr;+du@8X*z z?K9Q9ZpKvh9bvE@xevk(Nk0m_!c=&Tj(ho1r0Ok|;v4@O2*%3kC*{LKlelo;4fO*eQ-wHK5#Iu&e8)bsXF4-F+giNC-=Dj3U`{|ifD zsj&FUXV(cbS%Q=5*bZMZaGJZuzK<_o56a|iVMDu<>T>ab0u@zvm?!L0mnbAc7NaBf zIB7{;T#e`lo*W}or`z~=gbFkR$zqZN*akZlsuuQdUG4MgbL*WQ&kD-5YDXM5t!&h- zcY|Y*ETQ$^r7=Ow)UGCWynIh0Yo3HRM3&P=`1U(^GFeD1u44(JKry=~oRkj|$K5?6X!-=i1TY0Y_-8CGNY!^~C^Oq=4Ud=9*pJ64F;*T_ zSOx8A{rxmy|9|Vqtc3QNA;|Eiff-}$<6AO|A_FJh#ocp4dQWt|45j-A#OUD5KE=L` z3h4KJ@)!E!yt2rWOt-UZ6c{qCAF{=+_w7@#Uq_FdFtylH8?GqMwYumuvQVx#bSm3t zveB-u%fH#QeGl&c7F4|U?>gF`>F4QoyVAXbzGZyT62Z5qSwa>ILku4yN?s+}5s7E> zN<9qwu+p`IMv5A&zxeDdR6Z=6FpJghz3n89f`$fV#t>#=hR&PY_@?>gH2LCY@-(S< zQi9+0DXas=N-8!JqowK-;z!DCHZ&^=5ZR?%BNO*6h??`bV*qjt0*U`IvDz^F&$N7^ z3$*qZEfFN5tR4j8xxY^yb&0zVlpq#5-!J?@k;U}>@T43Q8~^*zu*>uMU7EL4_RMg- zgqF6H2W3D^>m%aPC~q1ZfjEbq=vfJi+n?V>X9(F(Sz15S_+6Z_kYAtBHFChDF*?{# zpK0()GOvZr0JGUf0h0EP#`-_mGS>6Slx;MI{`DeunwiDh=U(H*c3eD4wu9)LT1Bkr zw7K7|S&>tCiwFoL&tIe@-+9^NoV&}lik&D}@sX*p%}Z$Kz+fjt60OzUoj`YIR~QBL zwx1BUHBH>_4XK@wk>e7f)U&Gq#K^&U@SWu!~T{iY31L)>6G9H-Ev)>*o3Fk3MItxN9*AU3-VA zs!2eNr^g-3&|App_@4Z!Z0zR+CA{9Lw%R)^EAx|W_}5TKF+T{BqhLLf_0hXsR_;*2 zk*_*ZrmtqNBC0T2QjvJ5>Q2#+$2HO)r#fO;QCVIvw;+ieQ_nxe8B`n>8J)PVsbq`D zPfw_5m-pQXVh?9dr_H~ti|SN0;G%t{P9Gi+3AYZW#X=!sSa>gze+>l>9UJYM0H)t_ z_ah5$47kinCp<;qDd)2|*FMeydM`DVXTGrSKITP^_|LlksN`EU@(9c*q?-MF$X~&& z3-qvGVq)oGUi(O%R-d1ipIuAcUtHp<;utxMmXOR(kBTIPkI1C0! zu=#SKuc(VtiW7&6#4CMP)l^Saq@xn2rUIGeE1Q&~xiN9Uv;C!uDacXmkV z8Q834Mdoc*NMBvi$fSK{T3>rUIq_VAboytR1Y)4St!1K3Sw+5j%w3hyk{V&C(~by< zG8n%B)0cINffoKM%^1lFP&(;!ADO?15qUJOs;WU}#qa}u^5r&igvi6N4g2lCS3iO} zvHrb!mS%_g_tm@ZtgrvRMb7&79pNAU_uu}`$p1~q|3%3E<--5J!J(889VHpt$i&3N z$Y^14adByhgplwLK>DybLOwPriHw9qMO~diJUl8&NkHITeSN(Iq67-vn>WSC17o}c zDjGS8xX??*;x|rCPIh*74i04{CAS~kxJn&1-Lg20uBxiX=&-h!^4LUA68UUr2e`FQ~$0L>z!F^dwY9Z+f0q) zT3hhFm6a8Le}DK2$KAVkPfkwM)YMY1QQ_j^y1Tn;&Hho}n zs*Ro(+>Wb$Z7z7(iaEI|g&#kCYXAQIdwV-A6%`c?%}ljDEhi@@C1u+Cd#ev^ot>RI zIV;@`R)=#{SjfrApFAlt>WY5x;swzZ9*pRl&+C+7bK$!vQOUz_bMf*4^KuD=y-ECJ4<00hg@r{&N5{m_)@V_ys;k%3*1Eg69G{+YSWT2k#yr-l zb;7~MmS-T_Uufat;_|w>I7)f-Nl;L59)?ap5bX6QKR=(3kI%!yW3tR_u-^Ts{h@oF z=f!F2Jtf@fbS^$GY764TNf^`+9Fs(gEE2d*X zYu0P-n|HY#K`M-MZf?$M5-#boOV7#@BaG2;K_16PvtIm$KR)ZVd^}hg6mwnXHsG>4T=5_uC7By8DCs{t*X=CC5R`4sgV~%>~e-~=%>J>J#p73M%|8`akiT~Yy zzI`yNvo+hOL&%0tLK1WBI!5yu5Yw^=reqqt*6H zkF{#bY-VS=x+EPaVITrJ5QW~@*x1p`8XR7i=TlRfaut^48Fn?cznafa_MA5+sIlW> zKH}W#jbpbM%94wYW_NEeadJ9bA1_rY&{UI`r|67}tF1k&-D==*-8B>y6_r!=RFpm~ zEh({k^QK?w`ubp|jI1nde}<3KrDC8>9w<}aINX?wVb*Zk{Ua_{K~bJ;C-M5VX0d*2 zDF5Y`$VjTrxa>qe_lAqZNuL|I#OOU?B5C6g^Iy5_Q&Urg##e^`5pem>xBY1o@z9M# z77Xt|`fJy_9W3{!*)R3>#Icu_mJ&=O=_1{$o=a=8C-q%1EM8|Dl{`-CeO~d~6AaIv zA9t}d@_L?E(V33?NA}|F<@w2*-);4Ky*!tfm#I~EJAV8)o)2V+X3^1>l_l>~E`9as zKUl3dt3%l~4JR4!0dyhe(P3f59%pbel{YXjV8P05W*cN)oETcE`(nd~4<_58?kg!O z?q5K_oGirb?ChjkGG{91k}#=m53A@5hs-e3(wab4(Mo^)!f7)TA@hPhARe@lALs1b zy}2fz)a2?PFc1h!Sh)R#7#$1@jDYzkH~&I;F^}`6=zwrw?AdJM=e$3yw%5f$e*OB%yVresuqNC@N)IOn1K3;aVReyoA;A3aKTnu}w6rwgm#mHpoly|2 zUlu#vkYM$+)2E`z2~yK})?>8XVzfU^liT|HQ$UiH_wloBmv5d zn3t0VXUrGvL`on;(!|BZJ9>JQ=m;ec&j81$sfBZgX=rJemX-oBK1bx{t`+IEK(QM| zNRr4Qrw5k~V%-vQ-#Edrk z-V}aGZ~{@?9!jQTaY`c|{*09sUT-ZgKR4|omm3i{m9ee~1@4hZ6doKLOeHRXSW(VK zmLZC8ku>_pk4H?|AY4dTwCh~=7RO6X(o$1*cX$72vBky3aRU%RO8rdWIr1gZ#%l#g z-_}jBL%lSDNSBOe;ug)iJ2u6qJ+;IZ2R15Sy*nZ~XT< zo+BTaOX_o2j)#Pb(%<--o0|ceD;(F9t6zK^CWSnlDKm?pGs4u-nMDGQ*SXz$nL?e)0g(6ci3gses6xb^c*9P@+FQbTi$aYf9B63h?v$ z^3*`Y(lU=u6$=Q|8YCZN$URQ$^`#}1N^31==c8v4K-``_eTs#Jg^!O9*zw%++yxRc zR=g!WJ-zN=M1%igU!m4%LrCoo^%LY_3k4K{kemCoGl~)U3$UV4d>}}KD~bC|*(^p2 z_<-l!Abb17?vI#-g+)I+w+cn}tT={%oQQ;^5U?CTk<)q#&uBrB^3ZMqP$5e$4g2Oz z;U)=NCnxAfpY8qRpKb7P_ww=rD%{W9iBQf}_-m6BTJlX4mtbb~s-K?A5Nx$+MHC zB*@9PK;(qgUVZrV=?eH2Ol&|%2(b~P-u!oeM&-Odt1(M`s6mSW5W@8J4(nq(0E-@{ zE1AJb-r*4urBIPt14(phound%NAKCx?euWY`pMJm&M8Ve6A=?9zVL7Z02U2>NVFOM zc>f1w==t&QP>4oibjUQ>co=CD5dlFd@KPd1WkVB_z!IhAbH+@1g$yRG8pX%~$&1s2 zB#*;!2$f3nVTnj~<=3yffg&LJ$wDWQoH9#qZ!iDV`JRFdA2oKTC4?yf&Fd#~B^F0m z*w}HruDff6jn+0cES<`N>gp5W)RH3wTJgxbziI>_SXj3kKxc%FtGnQ!0$d9~&d0~+ z)vH&+;{j+G7*GctetdqEN)EGX&K$^Pzv%Z&z)AtAI$8F!n>3agUBmVu=F{Eg3# zUd3@(F<>i)B6B-|d-%AarMX!j3gJy+raL@Nd6kuwbdRqC^J*vasslO($N@|i9UVPY z1Cx-11h75+_`T-R&!i*{tGJy#sYK7y6_{FFvKLdw9a2Zdm6cl{Ip7n2&(B*=*H8xp zJ^(}oTC#m~M1r2H31tQN?}s&UPzCM5_e@@_T{HT%urQn^8Vd0OoPn5_xUIF--&(E$ zV7KKHE?m4hGu?O}&JCAzP;2z=6M`6cF6d&cNn6MR#!>3A`}gnvN#NE0Z^--r2+@9{ zwTkQc`MGkT_63scpKrIM=5@m<*O>OFvRjO>nf3`p5vNB0^V zm4GKfymL9Nt0GD!w9PSaNYmqaD6z3&R6qHzG$X?yRV^wk$0;O~zK@I`!3|c)*47r! zD0pFhz68Qit%Ig0r#oe$^F?aAt%=l3M=@lrDVwJO_`orC$xSx@(!d0{#1jNc0j2dyMJ>$8nl)k}%2madB=I&YsEwB7n`A_W8| z+4$*U={4QU0-eT7U@0MYo;Dww@f?u?3j=lNcC?v4Y@Yk(RaTBIl#yA_GpWcNv8CPw zn1MlHd~$t4P}GoPupE0LC#wtCo$6QYFqjR3MyLrI89XeSRkjfEsma}u5(~i6&tNQm z?@=Mn;mz{t&=uAO5M4P+xeceQxyi}oauv69faL+b7p8~x9b!3FfqIg=v@*Zzg&NjI2WzcD00sKujdR+mv z+O)oFz5S3HlrCX52Ea53X?#TI!k<5EP>+mz;{4wae`|-UpvXL*7#ALavQ6T$7m0kP z`SN8GSP8-OPl1*{w_kiMmt)SXUbY--l8BFBNL9{->CctV1_Q+hCI)JeJH$HD|5(2u zW>((^ts5YZObzO+ud+8=TU$N$`$b`TqTa;Yiibl^RXMB-%+2XmAJUeTm$PSFW>En2 z;NaqtAUfI22GYS$2#_DnfcR_EPPRWUY`y2Q<9n`j{Nyc??i8kV}6+lHdMYdw$Dtr5s}7;*zl%cY{1*+WHimoSZBL ztVpL(yV5=)h!EQstSLGpV0^3JysxJ!R@1!xqB}OyoB<9Pr}+>aOi!itG{{Lp#H}4D zGY`4!gd!P`Rj|L_-C3^F0Xcw<2--k-BCa>{AHpWb(sCR(CLCc&qqIa_p)LZWA|fL4 z{|j#8Fjx2f{Q1MAT~`J5Qlr8W--xkkV!{o`_ox3JkUrJ_Aee&J$|#jPOj?JlNQ8Cs zW?*P2tm8=XOP^wc_5gX~6tAnxo_J399x(}t^HT2vxtsyuF^#9Ij4)O{w|$p`VHII| zg?K)9Cs+>Q>;RB-T&%1Lk%Ercn3$@d;~^oKu`eaX#C{-|sst=zvT>T7U{6NBsVAT~ z)V+Gho?YT=fVTkd7r?phv6+&0jywb`J5VdatV$M0irWHHdc)&xBhT* z+Wl8EI*bHn{7K7=*}=iRw9pse^Wmd+IRf7RXbq6hG6s4LsNiVC`9=d|I#S{N1qWRK zhbE8;Tt=OdG1_h`fa8QPK|MViz(}SWJk9_&nVFe|chnakp;E=h*EcqBs;u4E-Hv~K z5)QMYrl$6%h*HqhtTXN*g+Um!1+7e07Sbv4f##Sg)ZvHkK>`6AB}B+xpkBWY;`6Mt z*YWgx?$4o~c` zqWodKhuhmlBN^h?OTS*iTm5bi4U{*sx3`aHH3^|pvI3xGwfpk}=|H|;fVy~eur?}8 zugK5BQmB-xtdw&RJ9gcyUIGb7yJbiqBl9zs)#M?!LzYUR zcBF8wyxA^;_ja>7j|z{YyJD=o>M z=n8~B7HmW?RUj(QVV+8UGQA=)o2=NFZw)+{RePPUj8xp?*h2=|p(mg~ z;6b3Niqu2-8qQ7c(fKcr4Spu_36Gc169(i|B_^yOGGJT8g1@|xt(_fczT1fIkix=3 zI(ZJ)tLmR$xxhMm1Y>mGnt}C#AS*GBY#jGztK3-b3lj!JuPiW?#2+1jz`s zEH!c*VAr2cenCP~5?mrqxg1N7jxu})k#t7HmR45nL3b%7lng;`q+)jeINtfK#yY;)NJa zm`gL{2@?|&6%~M!29i(huTVJO#dZJ2EoR8a~4O-Tb_M z3rDdsLlpZ?X=>AzImYaEqtn)m)%If!0G)^hEK5=_^C?Aw@DQDVen#6NDoQytFZQHb zT3QTXaMsq=sdM~bg2Vk5z5M>hn>fT9B~WD#Naa+;yXxiU<#r35kRRnpO)#vIKi);p z$kNI%2uQ+?gRu2hIzN zMC^kbH$H)!S)VAEBxIU|H+ZbmFjZ!zASa6f#+9$HZ)#+^B16L0uR_^3;tC75M9DnT zmlk(`M2~~;g^DHovNS_E7wNRx+wbk}LRq^^s;Yudha=!)o^eg4k+QNfP*7><5anDYhA40sYS?!X2t;CHqPI7A2NPg?K)QE! zcEZYor#C!YPUFdCA^`yhND5#7b&-JDrN|12ib5|8403ZeQc=-%5Ef$L>9TY%%#HPR zhr+MWpn^|J{bf-NRQc=Q15UBK`}K5M4E!rRJXMyCjWk$3dmsMi!GRJK^WZk1wUxWm zP<&trVA(Y_y>!6)CV;GWUlS7GHj@ch1T?@oVq##aT)~E-m5QSp?T%FMo?{Le7#zfz z`J6=xU9dn3BajdT!r!5pBa`%k8ITQ1Qocqdpnx1O6{u+j1_prm4}c1Q`X@mc$|@?R z|15lkGu_(#T_p5jy-^o2Um;f&@RF6mOm|mT|M!d3(Cqj-nWtbn0gl5=fwv43Q(avR zRv*z+AB-BB57X1rJv}|pe)#zl`eNUp4FT^0#muYEEdpGp?d|Qcv9T{-zGP)(L2)Q6 zD}%2fMBzn%%{@FkT@#Zfuzmp2x3*@%e*rEAlgnm3HP+UaF+VA&ZC-wg?74w|0hX4b zp`oRvrM|wtxw(0)j+C0JDzr+T^YDPo1=9or)(p&RG&DA|f$zt;wLb)NhehBJ68hfS zN)0W&1`i&f3LG5DqZuo1f1V+K-QArBxWBtQR7rS~Q&@6n!~s;pNi6CV#J*F`4Tf?V z5CHZ_!<*kC&h2EDIAWor`%#3z z{pJO=-}oMfX4Onk}4?r$s>V*YjP$Mm0Cjp)=AhDJ``Dr$8dA z2^I(5FY-34aqJj@3~$O+LANmixG|WJPpj;(v9LOR{^V?OC-)V68AFu@?#ovm=f}vF zRb+U0IP~5?nzPCEF+o%G6Abvn2hauVkVh|GG`!#9?@X7^hSP>)^CBfCMg=qjD32_S zzzL`k6MSd%JUl#9RDZxbho=O{c?C?@ypI<% zUpd!(R^E|Cs78fr+WU`ND6ok}P%g7T9Doo&Ff-86;Y|yI*oGK{1MG#yvsXGgI$F+s zpbbD~Re=o3Xk@U48u_nX2y_k_aW;S(t9#f^EamD6U%t?Z57av&tHtarKRJ0aq)X_F zQ&XTphOVM=rIBF3@_W62%6TNR4Bil6UFyAQ7HGzDajAu;1G`%B)VHzO`u$r0MnoeO z$9p(t0G!tXIs(21Lt>C2NL2^+`(`B*JG;`@j~HtgJS`mWG&zz*$?H z1X+yi&{~d{d~DeG5St8z9`Fq*YVJeNq(S91U>i92bFR>&k{lmSF5#cR?buo5j1^ABxBG)K)h`xW@9RU^gWlI~2sM>xRofwH zGIX|z=rH#Nz*K~WY9aK32_vb*)q!{C7B-movYrFX1X%zkB)I&4o2?7!8OTGs z%2p5jC@AI-x<6l>tp~C+jFlKk_DfmZ&Q}Jm?+fXVoOOV$l9i8hP)`5t1>g??_<#d! zPLRnb!1m(VEjXZkY?A0I5>2w5Lwx`KIY?W8=A214`AP~;sJOq|f>|%=0HMK2fjO|T znW-~-D-{hW5*g_L)e)2%us)=5s9Du_95FNqU;*U|tl(bAx3$vd8hI#M;Qhn#-vjP4 z{Z?!+u5(X*2+P*;N0VY9RNQr$DmZrBD)4X@vxAprN+U~qd(f5 zMz+9eoo%WQUuB6fL@}_jIe?1_9kSQr;!oGj`A_NS>BV0ok2;5y@J(9iCBp$g?75nq z34(?Mb{zl_3%GG@(;zj*CV7?3a?BQn3YEX+ECPr*kd`yxVfk~)$1Fe{eD2k3Z`)1_ zzLD$GgvO-E(S@oJIvU!YMjK~wasQ@!pE#|jRIe_+^vJ?50#`L1^X&kJ58^)St9j~D zqPsPa^wZY_Rd6OCloH)Hx#WsSHESHq;QJt6o*W-lmcXV9m>lptiXa4G454>f7sEs! z?i?NxPxs~lSdsBKSwe6F3n{F@l|Eu%V!DNc;{l4Y5t^64EtV_rZcmGOs^?dLQxC>S zVf~?cYbkr7X0`tI!E46W>1mJkv0^Z?0H2WT4wxe}%!MP_KWx5aeK{NX_3PXH<$l=p zfPUi!38>=vXTY4LBqb*ypTYi)z;yI+)D#n0x0mhMYD~=?4?;pMT==ZSS3y@xfEm1rwIvT77L)bwv z+)y1PpZykWeL&Wn$>sDme?Pxtm?dC%w4)LQaak}CkObMs-s(lV-llh4gUI+BpaRcF z(1(hoVL_u5A`--bQ2WzPAjHhvBxztcK2|Tw0tS3qx2}>68WYC9(H+a0s!;G099b{m z;NWNaZ@NY89ULS;i3Ke(WM00U*CXuUun+yZo;?c=pqsRbF7wc~yMm1aNYlp|9hVzK z+ik!+q>Tps9rOj2c!o@nt^vI@nh=I~I5v+{)6(D-UCk?_qO!6fW~V0u5U{sqxE8745w2;AF_wW6IcLVn! z+ft?x>~H~UL0&^(yb7r4ak`H`-D>`OdASO7V1Ggu2Q-LRM)KpArN2A?t_Bn&>G>N$ zhpTP!99Ks5Yl;c5lZdp=djWh!bES)u;&#OZEr?LXT8z(I8c)NLk948TR3L~iq+}S7Qg*scc=D;-bjG? zLD*RYwo4nE#?L$CtgQC%Ef_er{bCSZVB9b855T10cUb;RM~4g2Z2Ty&8fXseP8o0X z^0N0-7ZDW&U^9l?#nAa(t`0o1JAudf+q-MvE`Vyc0(FD5q#=Lro*U-{Ab$>n?@N9; zd`Z%W@=qB;VO_0P`48Oz_6DEBeiK<_J2Jb(j4ck?*H7#Bdp`_n`>%wDTz6ZgmlFa> z(=%tK3>#xix<$l{n}7cNS>*4{4Lhhn(OCdXo2Wa6P;0aJSAM!B)Dxdql8Tn=b+39FUb{`nC`qV1vwlL#n*ZogWb$Y&3m%VFc*hmFuzX^IR0tuzu*7J#%F)jvX>Lj5mAZt2On z1?^!Bn?lb*D2R8?iDUzbnSrYd(c44sbTnIm7JN3?e$w6BON`JBf!#tka7d{n#KWny z8s2g-Fi1p(>wqBv3INPnf|dePH7#g4@j=(4G|r?3IyDe@WV|l2ghGxbm6f9=_{F_o zB*UNRxHtyv&W_Phm4eoM(qLoo$yw_6!__V_FfRaxpth<*4%4ajAR8Fa3ARt1+SdVD z2<^fztR`TSh0tk~0|Pq*yZZ|GMQXA(?8T7J27v-Q7I%-1wzjWG*-UjWu3#}4l{nWx zFy_!`6XPl6cNTJCCmY{|mQS8q=`9UOXoHskC_UtJs{$*uWY_?xWn&R$E1M? zTS@M|jn(iev^TMysI;-!RtW?G3v9Zr&{nA21sZU$n}iZMBYH|+uB5Ohb55WRgodenzbD2&0bQmJblfXDJpVf%MX4qZTNut`&_w< zkBvcT9G{p_S5*a-?JFp!uAVa~k~8o1!prMw_fi32Xk=6m&3TAIJoE!2Gcz+Qt9(TU z$4UIDi+#@{v+OhWLfcy&&<=T>zzxdb4UofB%LA9S{7Psp-;=vL?D=TA>f0Y!iv z3xmM!z!2mF(FB?&UwQ2k0}@M?4*HnWnMQzzz(3$C#3X1&s8}H1KsHNCNC=5uX9(`Z z`qqeshPJ;tjEwA5-Em|NtYjuV)~-_}%)*rC$@ z^X>e9UFW*a*=O&~`#!^3_qy+Utp~^M>n%T)=f=I@Q&Bf9E0Gwm!$JXAj344<^M6QN z?BG*)x*x*ztDLZyJ4Z!KG=w&V#NdNrLRC;yJn=Jo`MbwH70Fhthg)E4B!)=wDpLq@ zr&POV=a=ph&p8Z!Bo9A*_%Mqa0nz_E(5$sJCp#PbvccE)+Rs`D0A)o*Cr3xVe0X&9 zCICM>gzpNn;LhEa}u7Qu7|Z(%n+MIlEyQgK_*`E%!#jXVz(L>|$y!Excq z9AIl}dC3Qd zjvjTl)8E!G8*PS<)8J$xgw-)){!7}W)<<&rHzHv^0?y8=2~;FxzOC@RXlGRfu5H`? z0k!?P104L?*~pf@_~8b}$5|-6b&Jw)BMuWJ8j4aICUZxPUGYdO(sp@CpA{jTYO?4L zf{dc%19wcrd`B2f!7v0SI=_j>2q@@IKHt?nIK6|w@ z&Ogg7dtav*Bg^qeBcf66jsY>hP_RPL!PJV<^>)fz|a7@7x)xqw|rB zRw(_TBfxfIK-;%@>#nE#QEG*Uqg)~7y09@gq@7-UUc^uQdBfyhaq*+yx8f%Tbpj`a zm~rXSn5~W9diK-96!itpJ$X@o4jg2`Yqps!%^{joJHbr%eSMpt;ui%-J@s>sbH;Tp z0>1$=g8*^r=Xkdo<+{1li55w7(B@-GhG0BTpxXIcbsJ*UF{1LJv|Gc8eVjUd!-$2O zZC?I4ci}?EI>{IcS?n(7&Yfdr5J+AlsXhJR`rC~n8B3k;V-pe*#KVtaazLxjy%2ch z#EGSBwBSZ3)sqBO{u|~!h}%rjh+_=?e17;z?jApqFBgX!2FTDoe{**My1Zz_JhBNi zkMUdI;oNFMtN_eqWDIw;4m9QL4+?BKT#&bu1^R_av2RLCcvO_%?~V;1Iwb1y(gSBD z@%uJB&0067PRpiGq|^Q!?n^ubI?6QPsKTB&M{bCEb8{;3IW0s*abPX^51hw zojoIpvHLttov!*aEq&j04heFa=}B*@^U{h)e=0h)(^Z5#*q(swyxK_}G3yaYp{OkBW_Lz-lb9}sMhPfYEd z;<)19T^{r1Jr|g&ojYZQYbQ}mQNc9i<`9{yFag1$z69iS+d7!v<@kitF}x0;l6y2}(Vxj&VZ5obs$(*#PvN2q?+@;4FBWlQ_`@#i4;#h@JNk9S=K6At zZciM~EWCb|i)DCr$*6xpdP3x!6qUB+I8NA6oKj5Fhf`7<5~k1+z#l=$!f>vrxSj=vl|GG`(bG`n;UD0#kP1gWsv0 z_ugrnO2QCgb=cI5%<%9&4ktB<-`z7GWH_ajg-R=;7fimTYIUMwe%{74CD8^Qzs|I0 z3E1B^^fbAD$xX=vNEcKxReuY)u}?6wuvhPDYBWqw7}~`e*<4;XD-!=~69wJ9ypCH)1obudAi~^&q zvQQ13Jo9s>A*v<^1!i1v|A=FJ>iq*uE?kJ3cx?RU3({sm#b5FDcj(?;cz%hMWJrCk z>jt0#6caU*eSv*yzd?guXM4=7$o;dIo*Uxs^j~*A!!+Q1GI}%jA}P4v{sm}sj&Nq$ zrUgOgFI<3F{uj$szqcQEd@0lAYQHkxBWO z&aE$YHNW5rQ$+oT{2c#2f1k1ePFzc)OXp`CAMg6?T{ zq&puFK(Pr}Ej`vRaF{j~w@l|GE^r?AzwbeHn@4>7vN#i`SL#(mu-{%dRu3;J5Qnp? zy`$2w;ImbcXCkpiovw=#>+7$>V3C~tGYa&A%`Sbe8WP%1Oe@Zp)W5g1WIkGF2hW=r zbYG~v2u6E$8Y$F_8%q+wDY$oMLAPDS(j$)+L^|;ifLKKU-(qNO>sO=1gbQwKTqV^ZoY%WD4yXdpV3`ROe@nYK=Y{H+J&-C;vT> zvjv-ceMRKoZm+*oko#_uATAqg-(P=LfQiTlLsfE$1)1RM@!S4$$*!KWPQ17gn8&G0 z&Tbo|s(K9h`l7#TTxDhD*jJk@eN+D!(j_vu-{zQTvq)0qTM}gPwaxgCy=-E4>?pz# zd?-GC!F#DH>od+mLajZL9|iyRwLvp^dxrDs)t|BQIHcDl2>EvU^uBVsqiV)S{k+z6 zN0kJX?2zF+Wy&3b>FQOhhMPY7vx1hDzNG~v4<0-Y%6JUogfO);I{8r-Hmz3iY{R8q zqXp(iH)MDkOqe8t(8uc zmB|j%1q|ira^m}c|C#xHjq{v!3xn!xUztBB4-gJ&6^Dj8KARrgZ^T?Jl}G#PolKrR zf4+_+U2+WS?@aA;Q)6Snw!8e*rRou`7f!NFE_C~~kJrwb`-SEar}QT)V6T%k>O=zu zWd8YxI(l|)jxArEjF;xvD64H3t*-J&o(=6cuze6HN+4T2#~d2VuRfW1kV zJBC+$8o*q$8)H^p!wsywKI!Nd=-90UV_G+S?M`4)#>JYO##1hDT|=b~9MZ2ADm&TIaRUo7j;shg~dL>|P&8 zQF;2$*dToAhktKA9vAoPw&Kj)2Y&S)^`Zb$JHD@*&cR~o<;lc;+-v9O&Nt~R63yD! z#X^#*6~4mW>ZcjhQ~;eGXXfVgiQh2?h)V^hW4b5>ardH7qJ%`Pfzkv*B@eFDqHyfU zZ|caR`(f{aMaILl6$LV)z6+{-!{fAr*Y-c8cx#D!zQn_0Y*1&wV||$?kI~Rh{qYS+ znHCjxC*xvfrta^4`p8@zY-+MbMgjhjmOn!ikwe~}3&}ETNsprjYBOojypwm;uW?~Ylvfpkaz#+~4rs|^9~$$V zGw52_^7;JT$v@rD)p@I3D-M%ft z-WU(V(b-rt%o*ToXDI%2z6Y!mKFxaSV-cD#dGrV25{N?;d-FHK?bzWt}3jU#rgv8(@0{P2;g(X*~2lG#jkWta3OK9RmH|%ipkFAX9`#b90 zFBfrN z?696OVVf}|0uKt_j(L0Oo+zAs-D9J!Dn_H!?1ZIu=opmc`Q9-Z( zfKPWnmz|xL^~3GlB69-I=63xXZA;p|)ztld+7L+&HFw>Zg=1q!&wdTAV`pVSp9}3$ zaC*s!qW=AJH-C3$<%AMs^5jsl04?zart)o)7qwCxy@b`F&iGn^je1VJ$elg6hZM22ocV{P=nE7sEp6^xRWcA?4;d8M8MVY4WmNs>e9eW499#5JxDtrEE&0~Tdl05w z?2o=&1?=y;?!ele?qzY$=)rQZm64PC&B2(QZu@v;PQuoXpwBP;<~zBl_V{*0KJ~Ml z=Hu-l8dok~Sv7k=;4?{THHBG}6Vs5THm?86p1pP9Skafpt*6ggfd z<)86tji_?=GTz2<=mC?`hgx9V z&bWTQr9KXy6g1>EM=1@4BeXTwO%q%BVS7sG84QRZm7g8^1frQ*@~v*;%3Qn7jPq|1*KIy5m+MtyVQnoHVS(Qbbzqz0MQSA>^u!H$h0lhb zz-^AnXwFI^(IlNpOfbk6mgz&g>3v>we$Jwuo;$7Y?@^a(QdU-;e0?NJtY*!jG)hS0VRw50ox$_Q%UrA|c z{-43Iu;9jenOrk_UZy?HXLv)pJy+Ns_LmBv%x_dZp$eaAV>r7#naZ zCW+1jc6RiY*&$dMF7Gr0kaIp8|4a=0pUF(YHi;gJ$D6N*dk*O30ZU^%t>VY$XM>A+ zb`oaZ>>CHss&V4(0-=BdWZ27KA4yA1wMg$?qdR4aR7LKqQ29qso+!N(Im0>#4XTrj zX3p`bk}#Lwa4J3h%=}zoQnR;@Pw)lNb-2`zk5b^YI+1)%8V0?~MofyMU4pZ=f3qh> zyu|TlFQDD0P3viEaPa(jgR&*t{m(yJ{Va0J>5L3-(`cdnDC(uh{_fwq-K+B%lDnI< zGI>LgkhehS~HU85R%m${Z))6d|e?6m{ZA(kNLWBhgq9Epw#Z2)cF@MY!msXe^r8Zv$a`YLf&h@qijqLhVHjZwxJ4W+%3YGzuW zZHK<=6L?Tl!o2)7>;f1{`|*O+h{}_4O-?O@^2}#wX-39yQH0_4N&g(bIy$t}J?O@m zL)us_BmOMZRodJ9Nt$+;+bgz3wf@r2-Sy0I7SmzwpK1dETPiGDu>#YXE#U;q@~c;` z>}41wlE0~`t8JA&1+0;g$To?{qN1!kNhcQ4r_goYF8L0o86;UBDabWkO%?DZ2rt}~ zSEm`sk%igq$Dafzo+;(n0w?NgEIUi6m;Nl;O-bU>e zA6a<}@-yR%w`Y&et7OQ6z1pC%8n5UJpN`Ct=-Oq|pc@(iW^PkdEe3~rHB6TpH^pf3 z^yzXQ>DFu4>eWs84Kl8gRhxSwAouK9y@(~-;ERKwf8l01so6HSH7ykf6D9gzbnw3p zljPk|M4r&9S)}`n#MW+564yVxcHw;a?o_iR40FV02YXHP^N z-xrhTqX-=*EaBH+=lx$^@j&P*z>&HTys}f8kQ5sADl9CX7B7lp|1a~9#b~M zKrU&1VYkCueD_=0*hpVnaZtXG%noBe=T9Kx5#Is@-ws1A_LPm>ao|9&vdL-MGmqOx zTWX19upT6d8vfU&o+vu=@zbZbzJ=}{9`Hk!>8TFR&fS$(uG+N*gIj=G+@q?hls~o? zv3^odnd@9!cE68JFQbdKU%&P`E_*HTr;^7%M?CRRQvZfHdZGs#HHO?8ySPx|-1>Hc zv+?k~pRC%utDceCVR7zb^yi^=0SDt|D@te#L>(ep$Vo}jI^8v5&3Hx@0LC_BGz14y zGf5ULw+Xm9dJ0N&I<)!X_B%<5iT3ku&d!{ap2492Z{o)uBe=Dy^$t z@7-(HD2@?9;nA`qDkaAo{B4@&m@Yj($9TG4=(R`Oj3-ZaIwEWAt~P$e(1dNTEm$i% zH%aHIh%-N7Vy{|i(D83**ylq>!z#+jLH`=2l94gkRP>+X#ek=a7bRR8QF?dxDpxvI z>g?ijFf6QNYu;F-h`5Ehsrc7+W@qir%NsZ0SXO#PdAah)MgRO8BvMc~93Q`C*)lED zp@m?kB&mj%d6%zWpAfO64;g`Qwzup>o*&~8dVAPx8W=rx#;JjyRrbfkJcDU1e(*qb z*nVk=U_t!bLp%tIEB1 zA5to};^x}2S+i$*Pe~y|`{d3S&pt@og_#l<&sW*D6W(bah2Aco+X|KT8Q)dEQNA7nL% zZCs>(khVD3R4WhVy8wJlg}yxW6mq=hf=&SN8{&zXX^J!fwUH7?GFjLwXI9H$sWp6XU<&5-Lsde*>~}$+LiN` zBfKUIHXo_*BwY=lJQ`X6UX0tyIEXfKlb5NARzy_P-8vtG#-XE!+LXO9(0?Eu?7hro z#&kP7iFN(vxw`JjyRuJ#CcuI<4``XcJ;H<dXA>MIwbde@Ow?|kadw|K;T<3k4 zsmnD&(a3LxzxVjePTH1$q?~V z<7YQ3Wz6ocvE}%taypWp?mB(?Gy)yx>1RjKg*llN^`l$lJ5aj)e|O~6@7uoJ9HE$n zK8@J-CNKxPs?2hQ&~oUY9viLCKl@B}F!$Y=gtblL(r))<%dq$)t8A43@V;J^@AV-ks14ar3Jf7i&VOTlmzEB z)-3QU+sFPdyS#PklR3Iawe~hkCHKd6vUmUfzVR5wK4KfKmt7Att@b&D24cZl7vIjj zmjQ7D%a)uc`mxNDEiJoUJ4dWqSMoMiB(yGF-H=gMupCR@zBzXT|8xe5g9TAJ*{Y|w z$QlpHn}rF472|Oofq;6@6UA$v9}YNY=cDx{9&|0dnO5wcUH9=pSkV%1<8NhUi@x`pK=8?j zf%s&&1m>#0Luj2(E;hvEQNTWhFLNu!!-xAdR7%?>!IFs`T^29an3FkG%EZ*P__6ly zRVpef#u*_*;+{v}d>UzJSh&K>N@_=F==h+{0k#SfM-GK6n#(&Xsj4!srkQxgytZyH z7GL#_h>To7mjNa?YSKluYt^xP*`G97vi5_D!?cY91K#x2u{gzvZmyQtF254n_7(NZ z03+CvuMG> zyF%EaK)EM}845&Si0O&6w7a{1NG~@|=-9VUR>txL*er?54f=~S_70A#k#C+nqt_7v zZUM^x{XTRS|dHgeeA;$&XJe?Uc?}+^(*C^6J&O>hhCxLT~Hq*OqL| zxqNw-rfllTlcA$lOXmMjObgj_tLDu`Ndw7Uw;Wttb~*Y4->Mn8{NMj5W%>A49>BnN z8|qv}FnHqIcjbQlw7(__r;W)D6d#`s@ zL}3HZF19LHiK4f$bcdrgVLS8X6^SNmV^NXJD_x*utb6EJHwsoQhUB_5|o+Vgh?W(?A&ZX{usm$1PQaP zzm$vn_}+HUF8KXGI(E3eeh>Y1@)kpf4t*ne^XZbMOELOcdC)Kdz#C$E%a>elF9EPz zJSMiLZEFvsDZ_PjZ=0Oj{z&dk%NhcS%HH}wES zh=szkMT^v5FPOpMe$%yv1TLf4dyeiCW*m)Nr#W=U5DIzO`Iffw`?j^FQdYDbw--Yu zyC;|h9@TXXUcXRJiGu>YCZ{}dQs%Vj-b|7RLKonq-zzBzy%1_={b*|WtWh7OS1?QH zrt7XDUwzKBwD@`@XH&l0<(NUVP^77>}=$jo})F^+qBwAwG8p;g!m3akz%&>u*b zgH&4fLG^ms&dCZA8oX}=xb?Cf5<=D&u92GSO_50jk+T|2ATb8itor`Pa3tVJG_ zme5FPRfJhH9#a*=CF!W#c6{5_^73*VpNOOq-y1RxdxIkjc~@pqrebXtB@`Z7bDiKP zd^GR5t9^Zajf{*EEBhIT#4)QYrmc1OQAT_OM?M2{l)RK~X>Bbi8cM{jjt}xjR_X4N zbBZLNp1!B7+>JXCeWA~YQKJ+;OtbtNReJi=sW-m{7MT_@PV}vB=7S%HbVCCz_xgOV z;Iq;EmsHsglhg)UcYplgCYigPd^cG>ytZl6oBiefD^{%v@%ZNZoo~m7CwBG@TD8Uw z$VSN~D=Qnv%&zz?p7emi8wYYOI2g;Hj&NJJkQpJJn2egRWZNH=vFV=5K-FzMcSN5` zP2E}T(L>|*lJoDj1g}_c4{))Px3Hc%wa1^+H!?G2brsb^0nA0imKrFO1?zJH*LOMi z?P{F7h4F$ub_H*nZf4lZ$;o-GAKsyAutZ|(bF0Sy{9FD1xqIcvaPRc=^qK)(3eq>a zJ$U%=uF2y?#q)L;mc-8W_czT^R30)U1%bAk$CpI*%{QS|Vzu>Bosi}%g*j)x~kdK)HBp=v$^7Ls_0*b=mDFYa>1jI31Io1FB zdm2C=fGMK5yql}H+Y}y^Ij^K-Aoc#s?M83o0h)syN;*DsCkTQR z3>q(;r^iBP4(O$=so7OVGjxI0g>&a_=I#q>ZHSztzUW28nT42uA>NWlk$#{KlSj4e z%H69p5LW&;>= z@aWN_M0GqqAHKI6NB(YP7zC{vg{7rul9Rg@Z}n!N2(+azs|N*#47ICP!hGP)nda<` zb7+j7UKs|}uxXdITra81OKGhLPll(}jr(}5)o|?CsI}7%c?LvhkHqTtZTO}6di~PY zXhT6!McR(;868yzVQqZ5j%&4fyxRLAdZmBC`boNETf&c=KkrTHnIu~9=AtnKDJp<@ zx_c5W6HHb7{(bkTaRW3&_yXnS|4Di01|rn*)17i)KrSf+E@Drs7N~e0g$VT<(C8^q zmQDonTD`eMMa#WH)8Ip*x-oL8AQ-fo80K_|K20a4qk#%&gny;!)AWR#HP4?seAtL8 zNg-0?<{dIqEE1-h0qBfXyDtqtS%|A?+xotx#w5Wd@v8%;)ASS`6_MDjBulhm!-kS+ zLqqL1Z_b_bW50CV@BEcDB?s=8l^yN4@F_Jo+hpgB8)g&6?z`*O{PxWo^}V-F=~9f= zd^R@kC6^#A(e;;K*BQ@6O|E2LVqiocL=TUmu)g-E)tKOh_xBhEu)MrHI*{P040@+Z zRLuHIn>%22PqmA=K)b(Kyp#IoB?*Ym5n@m1g=Al*zG9pO#bFO``?U5O%xQ1cF|r>{ zTRwpf*)(1)V##qbUh&I$bW>NVR7=O6%FGP-(>Wo+LP{giIv5N=pZBAO57)sI2{vA)5@S1rGA7_RecC5cVJv*Z-Q5ArsL%7l z23EpSV4KH9$p_eZ;R@aMzkdJzgI0va()xGhL=%(E=!F7N6g(1lWU-Swb^5yt-h*{? zq}Ok2`9Z*4?%<)NBA4*6hsUU=eOBdvMu<2t*$#`IOBSw`2Kj8So$viPv@=l zYGY&LNrzLn2N^ITv$s`!^3|)c5mvVy7cAKSY|mhMse5ymo`>=&$s3xyhHro$t1bT8 z>kLSNl9B+%l`<;CY-Qysq2=Vub3e@0w3w1pX^%AQ43rE$q|jEmU48d^oe?9}Fx!N! zx0e@6Y-Sx`s;yvI#nXx)oiJ+q;{PQ+;H9<;^GKoEq=SIwbiBkN7m~%phLJXEb!FNX z(kwb(FB8!qBBNW&{1S^d4@ydI_aB%{vUQG9Jb3rS{JX1<6KJ`DWy_4_&6~$WNiWNr zbgW|_=JtdgsCYqoC@6HrGid7fRoC?KtbbQ$9xLXy(7a(ErpJLmzDpD}N$xEw9MGxG zbcRi}l>^Sr(OnVggT%jT@#6C<9uG~IT`#6A<70zu3hq@1Uco<42gju~^8mT2 z2NMQI?-nY~Q&X94hZ1vg_BsTv4mw9)ynLDRYDWupg3(l+xT}S+a|GNOwzk1)+dtto z;rf#7qE0SMC1po=%a*v_z{$#lo4`_r799^bnsWgF-)Yu4nW zuXd-LIwhVsF`tuYFW+B9W#h+3bp-w7r2uRgIuGCb=~u2Or(J(~=g!WLKc~<+P~XsC zp>tJUN}}!MJPC_aOgHy<<3FOra7a^($n893nqPgn&?gO-7J6X`R=glK25+N+1vogT zbtnuyXQ2AoGX%tE)a7A8J%c@^HXl)taB!JEy_A18W%fF}HM6X(cjLRaBN)ZR#&$AG z3*^7>qNhScUrS8QX=&P>>CbI!?ak)zF& z_U>q3IAkU49fc!=lM**fk0kQuW*5RXY7?0cCk>;cAkMF2z=8fnM*s2gu?NSWwWBB* z+&bT4rZ^Lk&B%yxd0(4y6#fJ$KHo+_2C#yUZE45E5!XuiZ$U z{l1q%R(d)zWY-9b0ln_ty48(tMtBAyZiHrZSjnX$1JBYqT>3THCQaTBJed6F+}#~&GW32C*LuP9*03R25pi67?H;D zE37ZIuf8m|HGOU; zkr})db9|R9btL=(lt{jS)}}=vc>OcMV&$gsjNavsvc)|nFEWILktzgP0u>^=VT)(* zsUB~89|bc_<^2A6=yP7&$c!V+Ee|X1;bb)Ec>rd}J~Rw1MHnvU;&M4= z-8yZN49B-!RUZCFZVz@q(Wwl%cdMUf4+&0O%lBXFB^DnH0A^u*#7L|Ien1){}-lS6Ql*KNX8-y zOt~>VoUM+H?O+4A=P&QyUxD?4X0`CR(mth%IwlGdP4_7XXwT}BB9xx^==+^%n4S|C z9}f)=QL?$UVYav@Q%e)*9p|ScEm{yh;3R0NF7q8@K4!N2PkJ(Vox#JC$J$5u+FV1> zgn>MC;J^&{z(i4Bl3C6%weT&MY8e(zOnbnmkdt&EL2x~oQRgSN9*hOWST&({f5VeF z#O=er5)?;MYl#L|sjaymJKvQujmbB+*X`HRO3TQ|!{mfGO=IxWMD7>eiBRs}-{HnQcJ?MJS_6$b|eq5;I6oy*0=Wj>mxXesso|L_W} z#Jk^<#jm=&_sNZTy|pwBjv2+oeJM-yT2R(S3kKk4lvN(Py7l`PivpS zp_h>8-mmEv+_kxSOkZ*&*M{3k&qKc8|D(+0NJEXQw%@T~fDL~=WuJ1*moEbq6uJ~i zchzw8(UeMl0*gO*@Zh8fG3+~jAzroQ1<{$bvZKv|w*08Z`EKfW6_cwg#?BjQlD%G#wWbj{NL zoGAKBt^K0$ma5JE+{X#nP&t71G8&-_-`dyyG|hw)>)v`AB`;2OY1i%BnqP@Z`v5;6Z)u4nn1jju(BdqvTS86z}b6Z{%sEmn^jLT3+6j2^zB>s_HBqs zcz!znde)rtUDq!y7baC_I6ju|)-7bp^WM{jjhy&WYKz*SrvBh3T@x;-xkB<`&y_1T zf+66BI9GYTA05H(US8iQyF3Y7kF!&mCWUe;xM@oR#`Ut0h>4mg9h{iUsUGD~Hc7`} z%6^p`SQ@dFJ|x@=e41RHx-CgyIO4pYxA*p7HnrnxX$^58d!Gp#FG1^r3)C!!>T+-Z?jbBtEPP+lp_^x$b-d%*Cv&(&Ozp#*R zpkyDGm`-1D$>>Nz#T^~Bsw7@e$ja)yw(bZ@+uNqe9#R!hgu>$z&_pnRmad`l)$BRm zNsi*;<;x|PtJ?4v{4j(+3CW4BSRT%t8G(N5{_++%{r31bC`*$RlJ!a&pVJl06>)F9 zJ9<5*jXxyUGiT41aZk(2X4u)uf);RsL%WE2B*3ykBKX1gA|vj+F!_7o$-#2w@)suM zc6D3@p8?+A4@dlZ+2Az8eLGG35^mM( zuCi#0;S-cOFVR)%sXI*}5&W=a%NEOYeLN+`SdL46%Pb#3)_!!-rmZ!VSyp;;&i!L+ zAg$<^=>$IymewlDsDIxr+l10}U-gqglaIXhGRBZEBql^8dH@7H4g|@5=(=9G&0seu zR{yU50{=fS_!_H&b|TNBv?z5`Y8L(y}(NFwIv6Y2HnP&c|C*}3rAPkkPUxn94ODc*z9Lv@@p6cuc$pE z)X@za>O~L=NOWbj#%)Svx|Nu0xGgw=6Hjlm#jvPlEp(>touWKacR_Ry_N+2BFvQ?6 zV7csS5l&#k3scP?N@#FCsBEx=uSi!j4=Z49OJp<>w9$}{LBbdx#=zJNGH4pz(1_&r zZW8s0))DnIuJD%&hs^w2>J6B{Ag)TJ))F_%Awc0#<1d+VBrcSVm^K4P5mfR{M~Ue| z{9513n#KdMtdE6Mj%P*J_0~ZvR}K?tECPm5@h{0aNeCB4pn|lb*C(F*1gAy(r{SuD z1JwgHl5beo*zJt?5h5a9zF7NHs2lN7T1eFnP(M`AnL6N4oZSE!@xNUt}OiZ5r;F@L+^ zl?P72ASDZq#kBAs!&of&spH3yNpIMPCZ;2f{T0JQ=MEFW^tDMc*6#8Nrg^(zEIU%6!+|{cpwpAge?t80j%*&^O+mL-C zI!;1wQ4EAQ$`uX>{`vLgIK#t}!FG#Vh@E`aI_H#*9la(OK zL!(1#@t-jqDQ5E4D{P>j=objhKJ38A2YLIJGQ#h~iEb(ORK0e4qkU|M9BF&zsLLNR z-&AT#Vg=_g6Vk)oz5DX~CR}7f(y=n?`Ip#Vvi7IHv$Im&&tK%Aa9#Nm#}LPs^cr&J z#MP@EXlM2fs@##WhK9k8t%zhemO>qUf7DkD7CTPFk|1~;tja6s9tF{MPcie}uwjR0 za&&BLt?qT`sNZc(gCjI=m%|9bg^pNwExNFK0~QvF0r;Z#wx@f?Yp<`9AjfrIn1nEn- z8%(Aj*#Gh4Opf8^En5USoG51hpDJ?zM(FA7bPWBq^xr9cCCn{LCVb^aI;d@A2;i!? z?yFPJF)Q!fIcqz+&|m?!c#kWB<^w|c(8n&GlTU9uUIt|q6$|rN+nF=d#*ex}`V5zK z(~h;>y7fkW{>1lhv?xB$yE_CutgeOuSN-J!)FtY%fc*vzzMXvb>UFUTl>)W&H03XvNX3S6VAPLSnjIoqBRfOV`F0azfYGQ3^mB`v{;M#(i#!* z@p4u-2>m^=;S~=_gY)C%iIJDziPY4NA3fSVrD1A!6N5^=bkn@&Y@POEH=8wUy4q@l zmJ@F7r=Qa;i5;DRqYgB9-LFwCVhx^=uRqoc0(*n6()ad&l|4787S?!m3XOyhj+&d# zUAp$qXs&{c;4guvUc2@z(zQtI2Ck)UB6F!E<`$r-I{K{K$!wFe^K%UulTEv}#j}~T zPgozwmT;XjRlZO9sZ)vbeO5OAcM8@*{7AhdetI;zIiq%EY^x3yeuB=p>F)Ha1IxvP z&R4IDAPy{7HU@yKy>}@p`cekcRH7$twZR^%HE}GnX$l5>XrZif*fO?{I(Yz=f!P-} zhDSeb8LyUAJMYn%v7Ghz30sbSY#rME{_|&9D|rhLa=3JDt>MU#H+8g#TYH|ro_gYOM z&dG^fmYok26I(bD(>QDPr?+Cyh+aBWYVNcApoyK1wv3g4!xl^4x+ebpttLdP^mr&$ z!b&a^6}BsOoZrW$BL)GQc|OgRw}r&hj8dpn->jY+6(2vM$BEvmF)X)xx1SholB6^) zQw_4X2TZcF@J|SWUf7}aBK`BYLkGN{@ybwBBs1h$-`%$kUtXRYacrP?-=e=CGq{8= zShS#Ysv_yG(pg_Klrwz$<%k`gKD5372SOYLXkiy;tYEviV8EyZPF`O|;YjV_DH-7n zLAvu?@h`s@9lygYh+}x-2aMYY0PI!VXF8*eyMJ%l6L7U?`QpWY32&|dcJhdau~H^) zNVEANBRk(~gkICc*W+nue5|5aRChxS8nSrH*$Sn))NJ6LP^jEsN`v_R)*$Non{HM! zhg0HLhAoHT02PEdN_?TSXJGy@ACf$)Y%ennuz~!NBpNni#PSxy+1_Fkc*LRMCc-JF<5VX3NmLVIS6JL58lbRuOIpq@vEjNcDHy zm_|+vG{_pv<-|gnB+__z?v)rPx*Kl$X1|p)a^EdmyLLuRRXr(OYxs290=rmw^8Dlv zt}%xIDAC7n)xzZaWZ};|$z$K3NZMbKW2_MhY##YZh0(E`KK8B`tTOR?=Z+nm)Q!av zI`p9$4?nr=HZP9R{^tLy?K~Or{WtyKp_JFc5f*D`Z1-_nlU;>DF79y>af#b(u48fh zH?!cQ{UC3r*)&~_8T@yxOTO5gMT)$4Z=0hXg2(j56C3AN9u4zte6=7vX9M|s>5CXp zj8R?q5e%H~&$t8&LwEDIX}_xS*yPWk*@!}5^LUCLA+m8=P+Ye=h8mHZH~aewZB!)K z3EX*HQlOxu9ya`_-|#C`aE%{6@W7ylct*KE3VAvI_)u4enOuMZ%(sf3(8jUat{FNW z?85^{#>iDkgc6gymFl;x1P6?~wYt3hjc%4_d`~4O2j|OnZsE|te{OSZ5fX#i!5%3M z0_P*PDBqivrN32Ys+HApf}_3d_~;>N7%nbcI(xXO{TK7Nf`a~lHIFkc7b!E}NJpA- zoXg4o4b$QW@q;>hbADgVtWyK8)!!^E?E3w9DaPan4<00mns$IQA|v}oSXc)~Hiy1Y zHe4oEc3F(q=D~vy$I$U1>lEOavb0QIViyk4v~#3Ej$zm-4ZCtZ?*3q~cRu4_(lgzn)RC$Gcw9S-sn7engeW+t`Co)eP8WBD^?I3JcYTMbm6|D z)bM%|E+392vybt{j8^AdLxYw}?f8dY*hh!7xDWabuYnLe^$-n=~e6n!%Vr7SMiL_nABc+6~k zuC~|Q>LD)FVsAhAL_ES14kTn3&Pw~GdMf}VBRc68*bgI9`a2ND~Tyf-KkRs6GCA14C2^bk* zHppMXZsyF!Pt#R-Ujuy+DwD_nMNfrJpn#oY$PT&`&`x!8jha*ar%#p&9iY;lBq;FsYUs+r%;GHMJirV~TGmPw43@^tK^j~?~Wg&O zgxJvxk1F>f?k>!{#Q40G)&Qg=>)-#bzC=BN518e*w=ZYrh=9#kD?Ye?-vkOC)-XA_ zmf0FfBJ+M+9dZ{A5Xv|lA{4K4FdxcY~RXhTEb+X$B%!SLUp0Rwzjsy3%9nkV4Fr(QrTo%+jC0e_)owT zCWs9h)LXKGlg9I!&L1XN?k;EQ8c>IsP2$}kMdR0cJ>@Hah14j z$F5zw;DREO@9}OJ`Q=05M=ERN%)$Y&)7~(T<`s25U>WS5__<$BKOO)g{-iMnVGY2M zMZlm0oBYvjp0y$H)6A(U^NhT4ohID79h3%kxWnh$d72bA0ig4j_wj z7Zl^0T3VLPzrSa|Sm^=ZZtGJUM`}5ZfD2K+ymYQ5E46dI!(4rWx{ZnvgScS4x}>OJ zvG$_m6Ib09s>jPjdqn-NRgYbafJesl+e%<%b~e5KVhV#}6~+iukm z(FfWF5``6tkGUAlBy!#T>w^vz%WOo;eda?NbMB6g=a- z+qZ?OxCk(K8YqV0L@p!Yx2OkCl1jqhT)>8tkL_{U^Ga-l=8bv;NVX^m@|kIu;r)E`5%q1cR9*2RQu%oOBq$1 z{9hThjhJK^J#>SLQD)5kYMmJoJ-YuPeF`d$ZE>iD#``hBg6Ht0E2E9MTf`x4(XTtf zl09i#l}^zb4J%TzVims%EC&0bE*5)obA-$oY;9?|lrM)zS?B^HB3O5cl8<8O6hi=n zFF-otoPPN5!P2}|k&x};;v#O{Lz3UTW{3;*!`!(tDV{yDk52wN#AyBhz7nwwJQlIC z9Atysgj9qr&bIk-eRa-oQ5U8I?i)Bx$##zqS&WGtJ#0tshh1_wesJxYH51%Rl*K~= zfv1=|{-c)xk2ws`ira7 z0W#?=Z-Ar@g>_c>zyDLskxN?Ez^DC7*2<~y{xSzKBHYX@VdhSw#Wc{mUGb`+*iC#h zmXt!pRPDK71Z#bF{_hTAFpFoQle~4lo*(Vg#%_~=H@IxxM* z00IB8TgI0ach3cn{iVbcJ~M)Q=+N%A3UEck#1`WKsoONIt*mzVnvDM6KFuZ0B<>bN zpDb+&2qm}L`h-(3Vxy5vSp;7U`DAY!!P5$`pqA-VX1luPqGUovi|0(F*~hzfvUrFh zHtqS+Z#QAl8*mJ&~BSZQC~14AveYd*s7AlRzq$ zg#L%*0pmA)Ly@yT-NZXX??~!wD4zYBaSLpX_8_EEa_%j(h$K2t^>(whdB%Wj%)Nq^ z1S1GCyqcQYU8c`#F=BdujTa0b`}4ao2yWE=(4kpYR+6H_ij0M2c%yto$1>Q9=#Vec zq2)BB;JN5QjN!1AMNP_HPD@hI-reYcx%2fREC`U{B~9w@{`pG)QUL1Sm+<}z@;PZe zQ#`eC!ri^w>m1- z$IN(ef}CeraP|Ge1YxirR}2^KorIpWM{C^=E`P71tIL7e^4BLw)(^M!5NoI$yo(0C z!_mjW!NHpeK+#_W@yBozGA`jW?V2z4dn2Fdo3m)|z( z1mX4p7H3<9X4y|YW7VZLV=>;5TeDXRf|URr;%F3p?3f@u#kGFW#P~!~>|wiycO?Sh z1UY@&XT~ZUwd-yZ@?(Yz6s3a97*7~kLFfqc?8?srgS0d^Cy#W0j)L*r!L%+#i`{w2C-QIL}kd=p2IyRfqvOFVI66jSGa4Q{5`J9he4>16ulZw|Vx zC@+7G`Q_rO0o$!M-@d4@T0l70{OBd~6IC+IRK+^aH93%L zFsi~6QidTM46M9JjJ15`&s1q)pzy!{D$5ifV&{l*-_~8^RTZ9U#jYVQ(+Bt|^Fn(b zgjM0oVNw>M7;4_?A0MHwFFc|^Ihv@xUEYEsHg=RpuZRv|&JruM-Er~+uVP0d2S>-? zc4z{+%yr?lxNrM0k`J2BFr5M!^gsm-G#8&r&5=g2m zFC+;MuG!1*QXXJzwf_vod}^Iz$AmZO6V)@}pB!}_Rb`MKq0@Ico`e6(oOk(bg?~Js zM~TPD7GJlaLggG&-`F4W)B-WYV9p06i1iJa?>2tRf0?1v{8Bt&1ci2hhP@Q zpcFF8nczNQ{CL4_rfbI_PDoF~>kIO+j**}&b^hfbGll4IM1+Lo5WIpg)mcKaHNT0@ ze{$U6_(Tx$YW@bTu%_U__bZkUWJCa}F$q&>Ex53MSJ9F+&n^_vp)0dhfyto^l85r0 zWG*!C9sb&k^ektFa9Ky@wDQ#*aRi&_EyhSD(8rkTC@`Wodw6^MQpet$NN^y>s|6RNzxe@3QH}J zCx>>wko_oFH@KHcqO;`P{g`;!x=QC->uFoJb`sv1Werc-dqwH8b{@aQ>zEWVnF3Hi z@Ejen)Ht?Nz)1dEWY};NMoZB%t~l5s(anB5!Xa5WWa|~*&y3yf*x*IQ$cvi7 z1cLI1qM2V->!wG{XJb?;IDg-q5>B%$z_8wBimuWpvVQpygYF3r^Eu1B5F)f^%5drB)&$J0q1%HZRB4xc*nfek`MQfhhOJ8Qv$Ks<%ieVU>FuHLwLvq_6o125L< z3>eIqw{J~vr`G3w#8TSKRX`uNl424&^Rq1vddlNcj@lsT)iWR8K0bbP@WhzIrS5LI zK9c^n$*$_cK@-LgY?4}W56@C!T2wH=Ox#>Vv`Ts%E3;t1OZI$z{?-W$lcFgtUvdN5 z8GHwbJF4QS2a-&AmilOlf53mp*1-mtmv|9tC=Q8<{gnm|yw3AE(s$#6XkTO0m~_3z znB(rVeaI)g^#hW^uB|`ggp4PYDo3#V;2M80h@j|pj@dvXOv&*H;|vTG{QXt-goQCN zBmTyX&JX!T5WtB&_UwB2fi0YO`_unp?@hdVdf&J25JDvxLa2x`lqn6$P@#xK9~32$ zltw8k4Jt#%MlvN+Wh|N~lqpJ5iINa0r6d`mqMp~r?_T%)to8f>&sz6;t*>t%YPa{b zuj?F+^Ei*QS)dssLN75*PGR)1@V-a$g~apQ{P_(3n^)xj+uH+fF3(fAu~+~LFlSjS zL!GUy7n_^+m}Wd2a^nft3y>QGphUoVyfbnN3bOFv#NabJ*5aj)f~HMN&;=r)UvH52 zkvOUys!NZShsus{XVNb^n4lJSUl zv2Q3R=nZl&N4S2#p0&2N01_I?ZP~(%2231BTvxXVG+u~eIrSU}vW?BIuC>pvoMzR@ z!M>T8Q5?kK3ew>7AA#nvB}Sbd;LHq*_3N%Y#a#VH9ST`<&8^9c#YhK8QRMgW#bMjbtJr02BGwsv;c zJevg8%A*}oaRBWb5K$mJ-SgdefS4$kLXHpYXfy+;P@$qvs>@4f&D?P}nI%Hxl=ZQl;U>+R(w z$i|UTn%u}GXhhtR9$7&r5kA4s)(~vF&4!G&RNQJ@Y%Es1Yfry-JQE4PHPR~riuJNd zb||gAr!yV7WT3+i?*rBi2apg&xY&erdC8I~41ByY&)89Y3z-)spT%Wmmn13g z(JTS5B?UqR)on6rHqasw5J!V8DG8w&zBo5DO`BDz!?Y7KkVN08s7Z z8yWu2I{%AOm4$x8LQw@d*s>>j2k0DCvky1xRlgn-Nd5iVnGN@^(D4G3N6^#b!>9oE zKVs*!%xaQPqXUY11Ty3xN^xn^V^5zhJ{08z;sEZleWkj24@t@UR$2=K=;VTOh7qMF zo&FrKM`%HK7K&|7j*g)7Hl-<(pi&$*jy^Hx_<$1hD+uWD#5^5@7WgviPnJuz9Hwed z{TN37x9f#ZvpU+1T7J>YVNdGC*1X`f)M+`K6{=Q8cnrX!;EKa{-y%EQ%X`ul)<=-h zyH{`t1gnSydDslU`F9&T&ADrChDc&)R^vS<<>kTJI=)3SUUV}*0EA-vyysQluhLKg= z+|qs8VP%w6`ZWDY#nSt-onQFQ{vZfL@{l|I>NCJp22Q=XC$tZ-aFqo({q`v}Zg=zY z_UPr#RqjVLR7zs%-D)eWb?!O^rZeuoF1Ej&veo>E;{2)fyP@7H^1C%S+j`22ab81G zr)_1?@k4ksilJpG_7N;R<3#t?Q4qumCVV^GW?Y6{QFLqvJ1&PBkJ%lZ{_Xy|rtpXe zVws!B%sjHp0EHhn&sgu|XL8i1FUD#PG3H3Zx%WYXP#{cQym&v|_8?qTk@%{oLq@eR zTqtP#b~_Z*F#KNuY6kmX^IW>L1fPmWqZ>Ogy{(4%JA)hEnVOktqEb_hP)_WpgC>)q$zah5|JVP^)Tpe z?R~gUh`dv+>^bkupSHTouRV@PELyUJOzzV8^MQeI4NxmFGs~&@8k?#kaj)hpl`Dsx z#T(LJa&|evWJwT|SrO_A7;^@DQU#!nHtp~%Fl=E205xbWvwk0{tDiwKV7?j0Rj;g- z1IGs#sTmlaf+N0>3ZB)%j|WeI)6mobo+D_rle2-KQ{F5L%2YUg6-Qi;DOeaiwQJXU zUa22Z3SNp4;|?5f_+$=3H&Hn?2BATxz8;)Q+FP;(^&xn6*}um@qXSV96YZ=Vj4S2u zkmDJBW2D(QdW=&K9vomh`ph{HXQ6gVpPkTqmF9;T2MnPKMgD90K{bYCF+tyde1qatGy^xmHj5#HQ&yGI)-5dvi+eS}{KSOX* zhz~II^(4i-Nf`_7RJ$Qp!nT)zWQV62FyLTBM3-r`y})azEh>-f+1~xqCh_gNcI85z zXCthqwePGi?2`X+b?n<|1{n8%~nOHmM0!Cc;GJO={{q6w;#w9-X$O~92prw ze~(tg_LYv%QRu@B+!RT~5@*REPs zs2Ou@)H3EYvFHf>NbU@>D!&xnYgnH?P5#ZFv`?Jd*dh0G?w!|3Kf*`v4(y_G_N?Kv z%JUw}E~R-q3s}DSmG`;f-mkX28Fr~}{|6phgI6sPUEBMvw3x!j!%b}?emp46({dfy zNzXH@ef^A@-y*w0kNG^_czmbZ$i(IIN16UQI{J9eS2M$hQDT#YKq_4;uzzX;3)9s)M8!mGUK4jCjwleb=Q$Ceco`SJ34H+^dZ5ADKSnJJuYLzJ!x4~W5`TB4k!igF8@>FnQ{E$Raza-Wu##v4r$2nf^$=`Aih<2C5}TUSl1 z#HC0eS(!N{5o6;7r#O$4D^%y`d@C&rpTBsU-fBt#y`tuRD!C+U zIcp5*a5avF8>4SAF7L@3^h$;`;)sd1|HHxJIH(&JJWjrRdBPvbnq`X?T}ew@x@5`k zR(QTV;9VDj*QB0H(zN9v&70 z+Avi_`m2)5R9Xyv0dus2&7ZCiwXxIcG*h30%0CJbJk@|FYuAbf-Tq9yj43`NTpC@B zfEBKTkTIxScyUQjYT>lJz$BG_J1Q0^47J`PGR@cbH@ZaR7+a_~rpSJBw-dUNSOi=J zhU4|ef^Hs^K!h9Ow*As%7H*cdI-RgFcDYW)EP1I31NSCs)Etx#Go(s2Cu;q4x_@xw z&}ln?!Xd9G*{CU4)fac+;M z*Mr^9H9rklDFx)4mE})Rz~&f#E>E3OJ0ErImnp#0}AU;0pN3eS)x8MuoQkA>>d`~ggTaE6c*05!!-vVJzlwQ?;!CV`0I1$?0M1I4aQB6gq){a(Ct+d)TT^v@b8U- zyyvt)HR@<|biQpedM^xCD!ij^dWl9U#?p2EJ?g}^gMCE`5gmltNtO5}=YM?D!ah$3 zCe{Mv5!|`dWuHqZytXgBzplUt3OAp}M$yi(VliR072vOg9lj(b^SsIsTm~ zZ!l-h?y;nn0H#yOoJr64^LK}hOIugF<5bD{2?`I5UO)h#&{}|o-zWRfp2U@) z@k6UOMlzZLsn^**4kUHYqGAISziyBE@brx}DZ%=+IYtqff>jJ9w~!SUkJ5 zZp8|aLZNMVbF~XW+LkSCM6vs!M*}31`+1S0Awc-5Kvm_MMM7lao%;HEqaX5T7J*|x zj96hG(6LF)`d%<%O&JCi8F*}R_lC+!y&rcsO#n{yriJL$>G-0L9wo7d)6-iZd6YZG z%&I+6=+=4A&Vv!6D~zpq;hWvuPPIKA`iK-240HaE!dMzN9^r*Q471Qa%Jjl59;$_I z>!pcXgfZCzcetDb@%0LGPB%}6ty5!82E89sRoZCW9v-zRQx#R|3m%e8+3G0m< z4fG3Gt;cBH0wCC!{t|JNj0Z*2x#|*(9!@HBpDB%zr7XTtfs32BcPn+m6-nnazSRQf zLu-I(^fR0P=M^DO@kHYTZK1NM*$kw`Ia_QaO? zPMuWZ)ukAOO}G1|LfM_r1*p;xHjN0|5quAEgfC=irGzy?=3Tm3+VmM%ZY zmabzh=D4?m@U zOmo*&H4+&<%yEd_b9Fne2EQ#lC21)>nXpHE$J6NTBn1K~93mV!9w`ajZ2ps}lnxHX z5(jROjPND^GeT6KJJTwKg*A!_--L(6DB_$6A08DH#P7K}19OXICMjW!1c8XJ!#{Nn z5HydV3i%?eZfq=RdE@uQ!}Hl&94+rHTY3*xJ9}Wj-2@~s=zqk%A*Bnc(MSfyv-kHS z%;#icPeVh)ha{1XksdD1BH>6bzhb^oM&zR-*gnqCigVS90uzlWlV64LqQm^K>g#sW zCE(r(H1ly!qbtPEo)b{%zx}tSs)}XmOxj+@$)*~IbV-Ke1#P-U9F&J;E;$xh7iaX;nFE z_#$M12?OaZYJ8at&Hvb5)z*`kKDhQfQ%m#x@e=EMv#}#-X3e@@n7Yj;g!Cp@dx*=ilNEMo?~S; z<4xGzv{(S=VK#`0jwEi|tjPichW+Gt;!|Va>db@o$oiA(fxX-i$j7fo{)gXw>x#m= zP#MJ;vg_!EER+Zzj+3B235QtW-{C9!NEHB)3;}VX(UzBAG28w##@79u+u-Phq&@CLPPuipS?DNQqH@v`o7z zwQJV60eR1#Un5_t+)Y4CEKXb-6x1c?wp4**c|@Avr}GqevXcIMub%aJ9!sfD%31Ej%1RQsCvcs&&kad3_Ia%ZtgiA zl9c6Ya`I_eQTaSpn!J>PE(jnWegx-=Rj<82C4gtg4)Z5(95jxEgFg=(SmLlS#eNsT zC|9CwQ-G<*jM=Sfe3BOmsLhTbEC61ib2%K*v zyr=(R#0Xlo;$vgyx`vrF&Do7s3E3Z;f_w_j6**u-QlObEgqeN2cFhHQBp2SRyoq>UX&<53lE2Pz%F+N9Z5{A zP%|2b za3nHX>5iArbRgBzo=PE-m+Ed_drN3@{PIO}h-6e={~yPxy`VG%B#S#D?!GrMV5Z5I z>8R}*DoS^FB%6)H!E>}(RF;V~VvTvFoOEJQb~!a$a?;kUtZ~R8q02^J_uaR&<K0xDM(U41DQb+w|U+7O3b-jT>O(v->P(#oC(2FIB%XHGJ9R$;EAgq}J4L z({_pKx~5xDp5bwUtJn#A*yAMIM~~*cYr?p*c@E8w^E|!2Y3{4iyV;GC(4;Fk1bL;TIniRn6e+T{oOg!YF5izKeq^D1{huq zcvrZ#0~O-+(C&m;HbkvQjvm$ceAqy_-%`XHqoOuy9>blGQo&T@WdkX2>iBH3DDy>l zKwwJ@2#ubHQ~9}Y#V_0CG(H|VA_RNakKZj-njqdypEBOB?)#HvmUD}hHEHM1&+{3- z4iW>KromLHUr*8nDqQy#oPAM~W*VJ94-XS90%pql9ptwH{QzVLFLGhOJ=xL~v(2^) z$hW>yXc?FmKqkv4#Srx}JRm4?8*Gz|j~z&p))vQyL`4Z!6ox@O6 zZ>6>gHqT3ECHHppQWxa*he%1ip&La;R79kK)M zSHpJLuyLb9?AV6N*$Wx1MQx1p4X%vuW}hF;CvZOa#(Sa%(X9|y!KQQ9<$7g1|K6}# zF=P%@wT>P-WGM4%Jfl76wVfrusbY-i6PwJ@AK>L=xN&xPwYemu#C! zi5BU@oq7)t5jnB%WHrw%BC^2L#N;xScB16st~~oATYR^rF^1qag? zXT&BqHg;}4m&6beGJa%sKLm1xNxf8*ge%zv!gNLI8Z4lwYY%Q2seuhJ?=a-<<{$3V zd=-KMu1x@iciE*e$niX4Qq;e1;y?bbmH<@nQCmtSi!mic-?}o2oEE5%(1xlcZ^{Yn zfRupH)L;RnrKM{tJ@7cpsM?|0m6bXAZ)N6y_z@n8OG?J|lE&*2SE*@e#P`}XkY7#b z8ZpuMop(>>wa0+C0hqr+IpWXK22K4u`|s0C?i{d+Kz`o`4MA{<=r!r7%WyG0@;B%- z1lW-B23t0FfRA07xLKaflcUJt=d<-SiJ5Hj%AdkuWX9)Uy)#zrWM8|}ZO^7vZ+E_p zlco`>D3))xk#fG+MfkbFcrBvAzG9*h4_KzFL^Leojy03sP;Eu-@@zr^55sZBS$+BT z?MyG>cOJRFGNzO8OCRsbtHyqZr&WAoj?)lE3r-dgwnMA}$oz-Jv{G>vIr68B`2HOE zzxR4V0SZ364~caUpRZ%-cTApSOHv5g_LNZ{QC%|m;@N+0a=Ec^k0yzqKMT{h)s7WC zd-m$uhSOnTi|$SwL_{?i$O!L~A>YK)BR`PQkDI!vo7Y45u{xrVRBYCc$*3E^OS9J; z5g`aX#xIo1=ofbMsFC&paS@T3%_siu$)_9vAm$3!`#CuRt6pNA4F=}O)vFqoyH`yZ z2tmbtG*>kb`nz3B1TprgJSR$a5{ThYwHlUOGpSQONEOio$=ABR{=b+)3C z(%+?#_`5VS-_m^o()jif0VSemgCFOpcMB>yWNwTdcJK4Q-!H%D)E+4;i+i6zO47UR zWH$xUwZuf z_fR7;#NO7{8p`l`L#F`Ea+R5u9AMHohDr<+@8;yPUta9ndk%kJy?^h8k;J!mm+o6c zp#d!w*B!T4(L1hwOt{3f|GC8QuwYfXF7z0@6cxUKKoiF$u?_%v!O{ z`^--X&55eR-;ti$#|MGE9m2KzpVuSa-DmDs3v$Tg|6puYhFB3fGza_t+%t>uMG+CF zjrwrdXu5PCeV9<`2TUE_6ga^Dd%>bIGyT@sYV{v5VC6N}0M(JnAPjacD)`ezpj#Aa zMMMt&voBAxt*=nn|8pp?48MN0OtzfYjbN8JXP@e9pRf5EX4*qUM5ZeJJJEM|r5}cK zgzzJj72}L@PjIf(-X~-LI8fCq{(F%BZG_cmckQ$ICXC;tyYZw^ZX|~W-0BG;+pS2UP~k(1Fu^JV(UnbNglgv)_-xkg=@F zB6x@Jy#g^rnU9~T-U(Dzn)5Q`Po6q83AOw`%lYWvt3J!TXDYtos^6^u5Tn(da4+hX zm%C8yLz%D$_f#9m1L8(LA+})Ilg(rM&qWAj0y;bwM77QU42YS$&KO|C^0Gd0IJB<} z^!hAA<;6|`k^mIN{V^|-{+XARq{cU)l3Lbvz_@lrf|XMg*K5-RcrblO&DVq_Cj2b= z8TOEM>D2w>2h4Z;J=jk#;7gznj@rW!Ye;l)z&`|b ztb^{rLr$4I`Sc&ds`>BL&vAGEMh-)O`XSH*oMkV_El4M?({_^flV7dD!NIsMx^dL) zWq}@#f}o=kzV(kYY5Qk$ys_-yFl!=O$ESi1;eWKCYD-Rh_kolfZ5Q%oYGLkW9Y_(l zLNb(W8pyrB5c#`73Y9?%Es|{JCNHzYFfw?zk-;}`4NjdrsVn2+Kq-nn#bsDi!PGPf zlT(PA!60h|{~X=*-*wFR#pW6A_UKbsUREGmLUL^=j)D-0T!_NmtKbqCd51~-pr`TB z!t0EUE!ua&*4bIm3`fZ6NmuS{YM+0vw+Fa(8Wb;nHbY*5>>6+SqrSADtV|g2MHI?e z7w;D2Y+*!54DIW|g9l2ZMnS&F+VX=8FmvPrH9$Lzte2-};h!tZ{JXOKFm4PY8fBS` zRi`Hm6f}lNq(IN8+Te^=fGZw7T2CR+CVNA`%+Mo8n1et<%ZJpL3=)ZH9K7s27don8 z+QR#a6W*)))PLqGV&te%31(M@D=P=9KDXiYki-z;k}4B+kyuo=HG)5oDPlf(keTvl zC-1(!DtOi@PADlbnG*w5sJc+0ga^jh7}86A?b4-lT817qFgN$2AC@g0VQBTgd$xR- z8XllNG}1hJG(Y2_D3z$D^9#khoz7HcaP_{QRR>>2gpWf6jz9t6@0hTU3cdav#C(}S zgS;zcgdxf+N^rp#-b2bASZGT~P2{>Su9 z!&^bkx?J`VkPF2Nl6~L=;C?*)As)r8v2ZYhSmL%_h80_M%Y3Lz;K?{*i78;Ggwo17fOMT^2dIfzUd z79vDb0W)vev{zJjCz~EWzT?&Aiqx`3%omgLjE#&STvoaOLh!3_%jF-})dmAQk#~X) z0hFP7j%@>zipYgh|Mba|Q?jqpfk#LKWCjc%SOkj@AeNJtE;->)KkP^|B&lZt7HN9N z_?QBSKlF{&IVQqPnN5ida)!)|{#0b+;_eeTLKbzltI4kUN|nuQ$&!)nu}+%_$LYD{ ze7WD2WHQe$AWG<4ss1OaBLUihD@pW@oJ%4PFK+dOfmSgJM0B!)2a{!7&0l#Blz?L8 z*fC?)TTPoaJS;X=X!P2!qtFq$?fCI1zyB>a_Z3~VWzHoU*lldE-g-Z#h#c7(@P6X0 zQtBy`XGsJIrWiL4%+IwTlRyChsgEg85~Ed*TI^i@oIN`he1Sm z{njogY91j7*+oUI zn=lX%Nm2R|9axl6-1S%7Lq-jj9xx7*h2?|ksY3ITQsU#1zC?oGo0{et86m63()_Z{ zqz|3g@rgvk4U93s3vCvs;^O8+IeGBfQ&PS$&0U*$s+MV8U>N^R$p>_tk`|?hOqiET zznX@Q$tY~9AWjS8imWZo4C#TBCpQpALs8b4ur!bt!lmgcuxP78A~>DyMt^_*V~tZ* zV%1r4LqkJQ0@Mqxd3+v~FDu^lf79gjAQZ&_RNl z9MX)sy4aQhF%@b-hKh9hAo9%zpWOWIn*e-7MajG#DtpUj5{D*L!g_s#`_$wC+e&jDouy1R#3rZI~&Cf^pCG@s_WXAbm61H1q)o@Vy-j6%1- z#}^>d6H`;@q`ET>w!t2a-6qO=ckh-iI5-$e1vg&w#cn25SWXJm9*}*bC@1!0AZZFu zwuUnV+v_-3Rh+2CU79kW7z_QB8S*IyJAT#7(BAxs%xa=#D4;T_2}s{H0)4O-ib*F2eRX_RONFw(eRKcRq;;aD6ze^5tA9BRLch;PT$(nLaMZi95%c`!&gO3%^l$$601xy zIm-dcAJH~YQ;SsXdda$@{WrOalULR`Sij$~H#Ew)HNKuk#G5iX%<$XyOG!^opbwRHIjEr>F8xj%@+ik=l69G z#A}wrOS(IVb)r(n&!03gl-lOG12I8W{1<#-rAvx+s2%j}v3q1WZa=P8mqlgYOTHiLb#*NV`6k&J(g3QD{^G78UxRUKmTvkc;3pc6;7z3{>J8)oO_Q_;|zo}914g~A( zJl)#H<|zaU@&E|kf1_1W&~8Br{dyjrA7`Rm<(AG-2Wf;}0tK%!R-!(cR|+QRPkX(` z%9q*-u-vh6m>1lrnv^LW@-Sb3*ctNzp^G>{O%1YTg5{=VFTdx}pp&1!fJ2PwXWBwY zNMfVfa^-%*NcA{&0yaC@R(x$YWjvrTHyZku+0>KySO<65c;APj{voI7dV;G{+ynUG z^KuYG%FC%Mm;I3|B$tH&A3Wm)BLZzEb?w}V;$B{!k+Cr){f)Rb!Y~59E>>UZ+riwi zRq86T{JTsPNjY|+uNReHHWk6!;2bQi-;YH~+fiCenf;ylwe;b`-9G(9UJMPoZI^p-IF-~d z8O-vyPsaVk6X#AM8V39J&?=ar>YdO@rSJ{KIhmvHIQG+-kI z{T&S6`vP+a1Bw5SosX1Q0yT5EE>;z%OTE}2WVUL`%4ajTGQJGcfMs(a?68WPPBn)Q zp(6t-KFRFo=J(BW@51Odn`KSsTCN=uCMt%mJ}~3#$5$ zSu_Y>#?xozvS;X2!@dh>Q}5o18<_;GE-!!U<;!Dkn8fS0^PO7cWta-*obUA!M?JY`-1NyuWG!9A=@t4D1OC(8R+} z$8P}eqYt2ewE|@JksbY!k%jh@+m@(^OfPXG%vDc%Ea6Uc z1jzIWR+6mOxxOM(kHsaFh|Z)3xvaQ2;@5q6n!*VAhYE$>K-B^;W|fsoe-Ee)=82Ho zWlq)yVHhSW>`U}T*V^c1VojevKhN+O+q$5T4KuSDS5{hD8kJN*EkFYwO^ucyL;ZT$ zw^ZN-Fu~TgHq(UIQZP>-tBCrfODQSv)0wjpA8A16IIFo40vpxahcmy5%c_5b)J8o9 z&@3_lBi#VM>x+q!29+;Zdtvn)G}vS!>5}0n5WCXL>-LI%b>3Qjrc*$!&8M>D_%zE@ z=zYYRSQZT(K-@PD6pX0MSNQ%I+EPe05EO1i=rr*d6m_&CN%#7C=9(%qBLQcd2)9B56cv^*IED7cyAqs*F zrroHJ?iso=mnM+kzkbn2S^u2l#IIFbonM$CG)yy`r(B_%y0!<%DB;27COH|fjQuPmZbx*GGZ?exW+e3=F(vXS*>J*)JkCqfYA zLV=_K!=WNE*em!;g9(`yW(4%CN@nJUi>xm!>6M&($g0iPjwgrn+Z{tab}nQAj>lY3Tl=u zS%Os)G<|)(kq@$Os-_ygWU)8{23~fo5`P6u8EG&Q;@f*}4sx2neFTVGk(AfTeVFiQ zoGoFpQ;r9DBF)D11BdpWTS$&ndTB)|#Q=UO54=-VH3TPpS0ecG5UzujF|AC49Tx z9CZ0H5vH0f{I3`V2y?Djw5nSy4H?z^gdkDNo8GCJYgf}{al1NZSHmT zoqaeKN$8NI7G0$;2&*9zkp9~KS^ITiu0>?uWI-F6xG1c?P?~tkLiMUKAb^m^MS6kZ zsE=BCkPy&|ofWy|I9f3+1RX5@ELcarV^e9J@gU5I+_^l6tbJC=t?kC0IXw$3RDZBU z+>l3|c(*l_#`B;5Jm&@Z0ogtXq8|jQ1Qs*b15g~@P*8)g-l<~%g9*<_Ps4;ks%HaK zY_(MY!Esh$<5vSR!s#$o?|ZTgb_2p4b^WyIClVn}Ar^Z$x`2Lfs@PRymF4?TxdNzA zC`GB`3Mqiw(3$f9X_M&kuf_0GwK8<#;CL(JgdiJQLmXda9QabmMpjPTo7xHX;lr3Q zBSv(&Ub?9D)AdH>WgR3WFO$~xN|($ZB_#%25`D^0@s4o~-hVq`@)cT#+Kg~iQ^6L6$V+hs0D1=@l0bn9)SUogT;!XL| z^1bMKR{QQpPHlH^uzcxiRu-(is+Ht|w={=+GLiIb_$R=%C#%?Tk(>R6(+EIRH8tfP zyBm&1T|e3=5)%`dE%Z!G#2y++&I#^>Qx;y&E_aSyp#Ro^KYI+C=h06;W6_+K~_Q2VAiU5+&acyKY2UF67U`#%M;(>MDDci6=V4Xw)1J zTgk1T8hMwTa#WF^D!@6+^$qQbN&{y43CVBrrH{xqRZf5m|#w9oah8$&_HEsxQDR0N=(h1LIg1K@&qhN@QJ zkkL`;TjS8u2CtD$pH2)#<`P;j@&s@>bP8!yA_l>f(B-(Az4Y2)iuD{?(*EJ4273pt zc5+&faCHxLUgp4r)nfq^I=+bLO2G{x0gJa7cZSIj8k7Iv&hx zVE3mY0wbfceAaY*a+K$ILk4W~jc53Vh#x78l7`71|EP==Q3(xUcMt z)P08z4TLooZ|CInii-F{pDn^BXnE(Wr`NfB*#Z7ll{a#X2OaISXm01-M%2R| z!X=UPK)f3v2a0dES@2gkItip{;u3|@lVJdzuC5c(KYjRc?(}K>gf4%UAWm?oGLzLA z*g=2DqaYiBjQHR|M7#$|XvSn+!Htle#$b3Z?n+1u-jB33ug`NZ# zSsm@#)h8*;z*;vxqShlTMlb=u$8<8264~vUxkwyofZvFFR`Ff9D-*Ou?u?8O(y={?5K=X}QsZ|@~TA8}~!PM3hJ zxZA0-$x@*jKJ?KZ?jj>8KgvKxq}GrYCfLCeWsEh(MTqg4MC^a~}w?WqYX?9hb;XTbbK8gPALKR?hzpf{jHi9wTQ z(N-}DQcU4}9NAa&PGHkKJx9=rnAs&jm(`OdzB*}-n*Z1~Cy3P~~xX@HpRTWwf?b9shoDVg#+`Y6O> zWPv{oX;L2~cZB5!YYGYsR9<(xi|_=ep&MSicE}d=Cu|#>LbS_Qae%9lT~1CUV-=*|Y;wa9E14oi%D4yVhP``r zn7g}gUp~}8koIQ`V}n|1VJj-KbrW{xCfC4Gm1^npJ2~CyiRyRh(fzm zrtw5{>2KUPHmSE&eQ|v6>Tn78XXyRi+MgrDzHYRqVDvPSyrPaB^C8j(tNLDBw1&Ut zi8zERN8;Hk&8S=nqpaP2lZsJTA6a^`6NOZZ|HzYNRv1#USA8PIFShs;*vfKFG6ujw zz(locxUSb8zsa9^xX4Dj>_hyZmxS6AcqPDl1_{hd_M}!)HC62yafdhAD6=$4Q;OGi z&?s92j0WfI5b+{=6nj6q#*bJnMY?O(?d+XJpIm@}f~UwG-S%bN^7RWZby9vC(LX2C z_GN^4bf;=rb=4xZ|2(HvbpBR42Ho1VT5(`g8 zDrAF9=y8UcxYY(Adx)m%R-FxVl=~%^Cy#<`?$$3fwaja@*EvyIU9M<;@ z_%?#77)dSm_7}HCw)LfZh$V7Zt6&hAlSNPklIuL_p=o_dtv+EGH9G!$C59_e zPdV1;5uMnIii(<=*NlJT3j~x7+NG{m&&)U);Z@V_4?ZV|o=;dEcx=dmjWdBJPMx0)L}-M@Elo5iD?98_Qydu~}XXHGY-jS@I{iwt||Zb7tO z?q}&3n($031*#x>g%=m$Ca-oByqPl8&YePo1FsybAR6iSKga%S5}0IgJAe+I+c-hTAjOkbEC;Vu@XMMb)K=gy5& zQR(=e=nuU*v^Qb2%BWF0EV}P9S-Q0S{ZW^Lm?iZ1LUOgn_D!hdv0bfBTjXQqCFM?ZC9W*6YAQW6XY-Z25KD}&uuFX4_lG5)&Zi>K90yht@hs5_J z%>_M5J6a~APk|?#CBCU4LvR)!H9U-+vmhbYR?Mq%>WS!Xeq9;$>HfzLhJL(~rJ} zho#jR^|>`YOOoRGqAJ0PUr!{rHuEOXMyQM%&7V6@pB}-T*n`qyfJO+f`sSZhZFxDJ zn~0Secm?0ska`jA&8LNhXH9=mIB?h;oip~`mlmIK0i8smi-9#h)z!^Qz?4p(Fd@{U z`$UpAw~1v+azKVmWWL_iC5a{bNX6$U}q;aD= z2gp;4Htw^lV_FwDyohR4GR(|%rT;fwB~QZLij=IIieK&@hbzE+=eO& z&1F?v%t-pr*qDY>EdeYHtLOA!r@=c0Aq~7ReT3VrS@*zXI9N_XVl>DHYJ#@*(MjXi z5K~Z*tnbH3Ltb(8SLsEV;?PhM0QdsaCU!b8xtt8U`omHn^sJ8GE^b31bR%7#4oP?S zF5^N4!P(nkHL4DF*OekBHnUHZK>O9ySccB4Ld;sucXc7{ekiv_Fm74uh2oS<(8j4+ zaab%+6LoTG9NgFv&LlNRkKKg2ys${GvSKt~rygM0mcBBit7JTVLms>NuE^DJlmpS~ ze37!tXV6ypV1g8Kl^BcebSDZinZ*q6Z_1-Wg1%87vI#|=yLwhUS@jTl6|uW3l5O{$ zI%OSg4YM5*7;Gx#ohkc%{`91r?GM@vF-4c34=c8(-yv~d+XcOiUF% zRjrgNk)3{izpoQa_>H_q)FCrY%m)$PhhTC#Bdv}DuSL{5ts95Spd1FHN5HPnhkFJ_{dU{fSi?*iCb810f zNs&Skf=L|bqD;k46(;NIN?F@YICsSd&)X#a>(ig38v9bJ7_ z?4r|zZ9)%H&d$!AJGXz0=?Enm-*#_VG>mXSjdP|SNmIQ7l+0uKR#XuZu$Y#WeLsOL zC?`JofwqSb({vZ96~-O?`t?h>H|Xo)8^879kL)w5$1n|aL?sx8%S{mAWyL`?bp!eRH6^iVek1^nA*kLx-vX3B64=>dk@;Iygdm_DJU|+{f z{Tg^tf&g2Vv!T$BgLxzaeDo-%ufNT6E=>uvzF!AxVCXZg4M!EGwD5}AMe0%z!X7F> z^eu#HIX^udwyrSdQ&&pVYjxpcdUjMP4c)mD=u^v?5(vO!UyYG0)YHuCZmy2FD`MM= zhEYvJZ>55Sb#%x)L0%i*j-fMM;YA&hkdtJdm-h13%)_gZq1^Cp&ci9;G~7=7D}x@< zd#+&J{ctOROfo)6s>?D<%XMCX0n6(qIm9qw2HGQ-Pf=YuY9m56=@EQTA7FVtAzP?; ztl5e=|3`Q^3rvleZ<()!|508w!(8Ex39|$j!F>A*XMA?cT0a@W|1$@upe0 z%4XT}qAyzRI<6 zL6S}C5-a=EF)>Mjf+3-U01TgWuMEkz%@5kHir0pJH0N(w|QH^E9W0_9X}s5 znXbM{UcT-)8vGxq6C>xeoRhxV!Q$GhPjc;_cW$om-HfrcsmFYAt#ee&az+IwlKCnf z_Z*JsNs>K^Hqd;N#^r@Ac$beoOU!Jo+bQSg`R3PW>a`CX#GdhAnr@NZFFc$2y7fm{ zLvy2VYNfIRzYId(CrQMQ(X6g(pE7Y0!X?I?d155OwJr z#P@yaUc8|9^q(hI7Xw^pS!eHFJup>7yQ^`}#l{ovb7cW@|Cn1xk0D(dZ<(wpC%IFi z%Z@k^Dw&B-yd{Sxe7bm^@lrB(RlTIG+n7_aw-ja1XC zf_hKaZ2#K!>3YFOkztB41>nu+H^25$O0uW;$|o!)#L24dMJaY?Kue2(oUi-4eHwF0 zh8>SwHR0!*px&Sn>Phw(--=)FHAc+nF0$1j@n&;cx$~Z1H&Dd2YOl6>>AcydSaUO{ zNY;6x9)tq}F4mkgBE)_3X4!7X7;q355SAv=t;cAkfo&9`VmvE*BwviktIlXhD^CFV z*QoIM`n2!DfSGTyWvp)etlT4P=et{X4)e~ryx!OG`j6LJn2fUe?lQA&p}cEr+O!r< zZ?U-%R}N@V$`g80b35Aq6U>_SPn)x}Q3;S(@m4MUd&vr62jmn`rh4G@@Ei(v73~cb z!$bTnOXa+4PqHeB$;rj8w`+xx4M$j35|sNtwF&d@Ykn)#?>$KJNc(+RmzQpNDzGbp z9S83vlv?4Op6#k^aWucV_H+nM0<+agQ534s|I-+k$e}lSx$Zw_o$CML0(cJWa&c)r zXn@Pj?@RA4T~IuXU+j>O{ysKpqQ#bmRNGzs^>Q|6wY?I;ABVw5-7PyBJK7s- z``%SCyS$2{K!f*{rMBaw#2lYre*0Lvk+5&?7t=W7=+@iaBTz%)=4R@Lu z#^-UddWSQ)27uX)wrWvIKQt1SwB8r9EX|*q+uMvPxmEj@D54OD1^zPP-K;#{ZqM1U zr<-B;x2L8HvzI?GvsE{cR)tQdi`Dm2X*uYndhN}&ea#0FeMXkJttsv`{)X$FxXWha zh}lC@Ul!t%okGvGXn(q=Ka;*w4?e!cCTKR`~2rzKu;N%Iv`K+&eP ztiUgg>YQ@C{DNYtBEzg|O{ki&(n_la?6upP`VxewRUw@82 zwoNMQXZH9UdHHJh8&(~yr2>oa>T@bISzn_YZ#2JfKqH3t|Il)qlwRrgRTG|m|mONg^%5B(TgbJzKCtkdGjHWkEH0c0o>xKqMcDBy5q>|J^!#GV*>;ts)^GPq37&*BER?sV~v* z`-L2t%Rv*jSoZJ7~=axv#~Z)({NXObR$)xN{lh;Px7IQGc?m-xlz>lMG9FIug$m^nUP zf&aaW4qIug7mVs~_M^e4qf8a!i@h3e{;&m8sc?_KOO!6>`>hCLX_hr&uhqcmL++nu zh?7p+$KEFa+$>xHa}#3BErM1yYAQCed<@;vMlc}xk^I9 zH?~K<+s~q#B1!ehT537KU|jir7B`!drN_TCazJU zrdnj+*6tGq#t)HvAffT{Ga~F+-<}we)W_@BX|I`cu=*(ZDZ7}3F<_fmZx1o$V6q(k zZNdW7uc+Al(P3j97>HkMag6X>*r$bnMHgKME)|a2=FG3rW{ciE)yQnx2h*j4+F?}n z&wg1Ict$y&&jDpm)!!Xv49c5;?(7UA+m~inf;>vh*ZqFm+u!r!l?SdJzH{!?ujnGO z?%~kQFBy2U+icOQRlIF~G8>3!ck@)QJBnow38IAK@nGm?AJ}3pH=6GA%>hwkrTVHq znvgJ3Ny%#SD-R(`5_}1Eo?0-y?HA4ucFH5uU*E|6%2_`lY*Iaa!-xdm?LZ~9+ z?uHo7z{sEvc7M6@5kf|&AXZ-02TCnAqM8xLY z&eunPANnUvE{+s8nMZSlb7sqXmb@HOc;(K6XoVrS^d~#6yByXie*CpTV$MEw=kasG z4DxOrD&BE>!&PcC@Z8h#Yvf>jpB`L&X zU^A-1jSi|>de0g2bJaJ!hds8MT`J)~ej#SKn2^v;6wJ#px3p|VxHxCiCFyu$d^<#m_&S zgnbkePt*H%Ch7&}h}K_zwX){@`}QiO8R>QBFZ}ZJw;^?DYS^MV7c&h6n{=jZ~hN@ei|l>{v5!4M|0PX=ZaOo6jEyjT{zT574Ccr49k~ z1mZq~3NpFd$S4cxwVgjS?cF%tQR(37Jg0rG$G+y6Pubx#e(z##?A^MT!xn|vN58$e z9N~)g4-5TUFS+>U)qI_uCRyV$Y2KoFGBAxGwcmQ8LxI|laeQ&L8=5I8X=&a%$7%IhlPKnH zS-=!aYMXrU1b;tx(+uZe6^gQGQi3@BX!~s(pM2?3{s(u4GzuTw&F0O$=NFCH7OH5! zYBxaADa!PJWl!NpD~>jvN4?Uc)UxKgx5|KC3fnd&*e`!+&}VmLxRI(C=kK-e56gKU zn!Yx6>l^@m>0^E;;ygY=P)|z{NID-nOL-tgS;E%yF-F32*;U7vd4{QBgw9m&0FST>$wdfUgzd$Qd=`mK_WVgqg0-lmI8 zp&2|cFbr6D1n)fP7H@CABP8IHnn$w$}541LG4jH(|TXVzX-+mpp)a9P{@;o)&Lr*NL!vACDzQw$rwO;aF zrZ{%<+xc$%oCkgqFHPs1JilIZ$gt<`jPV&AQfweZQ<|=7l0%Li>e+h6^>KIgH}*Gc zhCJ5|SCsfV$kFDBhh^#ach~n!x<7Eub4?Z`@V30_oG$K`a)&gUpDRT!p1o*?*EO}6 zf(HY&n;lH%Y1ItaGy7omhHIvk^*=3jKCAyo$?U(i>EpMR?c^nYKC6c4X-NG0S|oV# zng7+TC;vF~kM@i3Z(B9>AO2CS5dNc5eDohF5aH|p`vd=XmHz*Zw|>2W|T zVdK8O2c+hS#m<_rKH}`Ed-DeEOYOY1XqIb2M5t=8)M{NZg>8M~r0yRY*LVAb8@+_m z`;{*2e9gO}3Wj6u73EYMAJf|_DBAbr{^K(p)>(PDoE>q|+gsoAwu#)@y;8ctk+ylE zm(Jz7c`w!T^0wY^9gqdmjQ8`8pGN{^ZM3_ zuODW0d5e7YEalYP{WcE9r>2a^Js5MqhmC=(O% zdIKW^$O(M}zGs-{sS)>FPiqyyEPH~TsC0Cbr1dLIW6>k0`ZRa90cx?-BK*gJ0`dV( z8kJgkm3Xb{&K|@1w<9>ds|ssp0{qt}u9qjymnXj0zTnVo%rT7jA%yfucZ3dPeh($= zMkj=7O0i5+dFYye{NnOz`8!H!tzoi0eRmrF=C>W4JX~=OgB)u8MCPp((_r^WGJp~8 zHLF+rKBY*gFmF{I1-Fffxx&TXNMxSbvfPkr7~ zm?u3kBh2IX7u`IaAI@*_LskjEIQjvm-qNRUy9M$b0o$#~W{TO6fCO1l)D*~zEcL~N zvGE@9puwp%B=sO(KT92^mhC{41R(I+)%QwoSmm%X(Q}uBW`sd~9f_ zbcUA9cyW`ndS$X+mFVv>8lEd#psYc$5AENg$O*d^Kjs}Uz4XuSVNa+K#T|m=F+7$F zBeVQJlXr3|gQ7iT(alV2Az0nJM3v>g^*$Gx{C*YT8gQ;OTd8*J;c=m$>XmtDyKNG5 zdy%bI0N(4Co|tMn?dW}$#Yl;9(d=#gfXMp5_FNVd(+t&Wsxr4d6vH`jUhcfBJ|NUi zX32pP&?|xQ7&HGWu;A07(*e<0(QGAWy_?JO3&?lF3C>fDWsL z10Q@oJHoHZIkn}8*_6_C+)B)U4LR(K-I!bkhYMuGp}%#F-GKFG#n(NNtFca0FV%|A z&%<^p{2M6>alsQhmDySzf!1@c5-QwYHgy#&Tq=6c7mht0nEh5F%hAq-Vgdp5gn|<- z8#IuV5OjJlZHPL-l(>q-B89&XV|`a*nzo?8W6yqQis%+mVm3)|RPIb$6V=|0dTx|e zR?pn46kMk^>m)+*~UGIrXY}exIRSg3heCwzR%b0Y%q{TE%%PqqB{GpJd3|xyJ?9`t!nulSPmhad z+F0-_VUFXseZP@prspL_fLtWyyCUDyfN&as3>m-+JlycGrD&~>HEuRs(regtviHul zTAF+XD~;2ur{SC_=+vtygJDQ>y7S5HnvtzeGp~se)hmY$vV|3V|8V9y`FXV!?02&X zV|wddVW}L|-a$zVMnC@*lVLqwmrV8=C%FRJ_xX+LYfS3b!%@t1U@UC~ekaWh@7P z(b*uQ)r&CY;txxQ7e_iRg?$IXLS$5r-a)g@Nd(yOo|%q5{klIyy^TKQV!tH4TelJ0Gp+~%&U=av zBPe7+;!RsSS5FI)U0OCIb)1;IIdrqne$!Zqyd>5Dom3f|$<8ZZ2jg@i1ScQjFNHkI zI_yKQE28$q{sjsbDFtZKc|5aINA8Z=nS zeG0yQcc_|13)QnKRDcsaeoeucwbDJj`{KK3h=o-ZPawh%<%_nO1+O2H)1fC7heq-F zaV9crrLt>mE>=v3V`gdt^3NBQeSVfn342U>lW$>}*lc zpI^i8wNz2}3D2n~d%>E5zdx8Jv$Nv5I(+UFcD7ON>C;v+Vu1|X^SSA#%qE&AV~_km5#H^*`g8wBt%s()AnJ;!DoOULnO#=NGske zm^FfX=_v$L|F7J*NoEb!hEzClVy-LIw&>cf9I%ncV3{Qg+5rkU6@Uq(?n0b9x@~&DCT<*k z*qbw8j=b7psFuyqa z-05?Qn*J_$mEtI(;i8xhJ)xxI{bw)7$Lw56Gw#w+76Xkm&&r>oq%eK#yjq440b>fE zh7NNQ&suGccEqhme3h(?Pu=7mcr7G+gl{a%(5=E81*K1Ei5eM6nxPaxF$x-Y>pGm> z171@YH>(THN<2>{JRh7lDM6A3@{ZVEHgJa*ItGZXEKi;pl&{_VR!W6!{NBz;>!>Jz zmWX@xHS||s=JQ`TP4-F=2&fIB<3yPmuHx&U<$-a+7FQRJC59uM{$zu(#!>|qc_w`r zU%Su{I~W~)5Wg@*jy}fd6-;~lB8*&MD4g*Q?kqWJ`Bj}?m*|uh&9s#4G^*~$3_3{U zl_l=XR9TLg94V?eqr<|dO3`&S{wyLeJ1L{rk)^B+#H zn$r6+GTs|gI2s)Sy5VxRMKX5c85W}^nnB?@anln{C}uB_5%kxaM21jLZ^QGl<1Cn7 zjpfA3+_hxcvoY;f)9<rj@IjCl&f^lH@@*{^v&+EMT)dg}VT1HDJ_Z)!1bky{&jNl8p{K|m) zfbgfXk>D9trkZKNKS{K}J%^}{wepa%qayP@YiZei&m9tDCX7;;*U5XZI*_b^Kj7-b zE?|+}=CA*Qb9%ZdM%jzV)Z~2(;{q@{YZu_d?Zw+~;sokIa%){gcZu-E!rk1{n^nn& z2-C}c0~fC!5jwLkvu7nYF@-Jrdy2JTqPyiG+fV`>@TdiI4rW9B<-CjimlfpWLrQIx z&Z7grxhU4aI%qV#Raqp;_F5mH!ld3WKju$gGN7PvcVeUgysqY*+@BOvku=b90#`?W z)SrVzaSWkLh&o21x|j|jy?&dj^b+WOGR@0)fOcl2pI zbY8u>pkln-x~?&rBOYwBeBJSHon}qSd7~UE$b5&lXQ{g}>sLwgnfHyOfQkTxj?DZe zgQJ1!8AI=!`&iMXOL6eEHrcf+5e(97_>vmoN9oMZCrj36B&Nu^mFZD#Jz{ zV3i{dhy28{H#}UJzkVogIsI4;kb9N$8zZp0QAIv`mVdgQF~-3YtBOrcEZtLJI4M)p zrl1jZnW9uo^1lajy)*H+I<8X?bns9m2JSH!B?OMOKM)V#qu_l~KrVjFAVK~R{jxT} z6XyUX-J?JFQ{O2lp2s&`6C(xgdYkZ!=A}jF(bi?qSs7T#h?Vi^!E3;2KLt|rUJWud zd>9E_In`|_Ke$qXrt=FS9RruWLoGlJZyN1If##1lhV9|lhHpwneYuOv0)R|(tgFYaS-tq$m& zeAe=w?!@MqZI%2mafuJ;bHfe*q61_$9a{6;q$W%M`QfrDk+9WKUpo0+|KciblZ+*n z#8d}bBixHEdpqNV{xealq~qw3u1u%V89!l=i!r2p<>P#1+`P1TyuPxs%E__VqDdZD zj$Bf67FF>oCNy+jth~AS1$Ma95^`MempXdn@QcxVzsFO?{4q5jtHCH5tgHHt$%%$& z5N51_Nq!U?4HM)VRuiG3oZFhZK%9^i;r0A=wbI56UFKK`B&-{YbfSu(y%t%%*HLM} zwpe2Tkuy1b53v1siFh+v0sq0Z=dv$G>lyhjHnTUBQ*o~L;x<7=eYL~SbtGMxdpK8B z4DeYGSKlf?Ra4e{3J&ih2p1Ru0(umLDbJAevQMvVSF@;1rS)+6BD2)B3J=X?8;$jX z219ZWEidy#Ifkc6mB+g-rtfx}CsYRIa+Gc67AiRw4d=3q#p~@)`{%+wv^-Lg*zlxl zC~dM@o|Qk0C~4XvVGr)_aNQG4eo)JnGyXpoU@!-Y2SWUs2#%>vgc*OsjKnZ(JN+#d zPCa?kG3~(_)zGIfn3{X`#4+lq1lcWMO6tR;VFC~Ieiu$w9a|01KU+Uh*M*9Dnyd>P z9t5$W6)`T`vlL*~PNlomN+a9oQ+|GIO!@1%uep`~ zEA|N+|L2(+FXt;=zuY-$JqhUE6q8Q)Hwiq3CRQggrjO!FN1)qF%BsSQ-4N|PNeGN> zDESA+SM{A?C(efHrVd`GGm5|IMbLA==sM^66)Z|@C-0uVOn=?jYH2fA-2f}eb+D5q z_2yPB8x}=X1H*Z3+eZvn5vC)lly#tJJRrt4@L=E7D;#z-4Aom7$XG$88|7j!|Exya z%*htV3#W7bdg>I&R(z$OclE4!iN~~%U+zhgyrc~kmFFQhG9p~x$qE!RFe&j4+`$cS z0?`)`&}mOUK+4&(+!jOVB)<2*0qDG%pYw8Y^S?rjKI?(3rBKB(s-Q(&aMcVm5*r(> zUYfWomxNS{;%%|R9c$|gL*6GzMuGBzVy3N5!||4(@qr<3 za!@o!2#`Zucj#CVKf^P}5X#5B_tc*2m@W|z*DS~aH^0)1Qq-RPo-Oob4!R0uX*B9h zW%g-m*I#W&14Zd)Ye|7i@3AzCvQ4klYC5e@@Pz*7h20bPrdl3(oIx|98LhLL+BP4Zak@?~gcN3S&((7| z92F7QHd`Fgoj3c53ED7=k#n>KxQ%NH^4}e}T?<(=>5$3E%uk!Hk{(zwI8>!=DnLtG z4VG&pKe$J*6y0TUp|3+GIlkd#fHd8QDZ>Tc*Lr7oULCm}i+y~~de2Q8fd}-~(+_ zvn3)G&6%1_4A#wRpq1ky7yzyZxfUa>$v@<{@}t(L;7p+j1fdfaxQ)Dymlen2kf#i? zht(`N_aV_~bVw0K#ug-FsXfWi*|phG3lB}KBN@b`*%Y3qy1J-R{Zfr=BY(bD$PGCN zv%Q}ltz_V0ZON%SEtYp|z^lW+D~3C*s1JrW#G48nCrEw4>YO<#S(!d-R1J+afRE9M z;xZv>Q=oy_ZwpLoF zNh~J>?{B>so+`t(q*sJkyF7j3BLvNTdM<3dj%IKic(uJMR%Yf`zO9<)6<}gAW#v0D zr0j6WocQHQFr~{KorNiLZ!|DKK!UlZ`|5`UG*q#;@G$zE@rx4mh2|hy&tvR~aqAeM zpLVDpqX?`rYy`gUPJoHG1^nmJ1iKq2UNsF3MUQl9>C{g#?8wAGhD3IE0cr-O&%ptP zE9)|ureAsyvO*bs-{_LJbtjU)*ip)WGF?GUQu(%9#dpi^CTLG zqM1fx3c)$k6ZNw_+OJ{=TtDims;mmu#dDcUOVE^S(VVVXHyd~}t+ul~6_?yV^&}d~ zQfOQ*l9I~L6zu1>^D+?+MVLdbM*~MX{9Ienw)kCTR%zu%$PP47L5+*w+Kz(@HKdx;3K; z>$vD518rFD4Eg-nO_iUlX*{tor3a*tVUf?<T z>ZJmni(oH*UR33MTx%D%Q*33YuM+c-5GA1jUN`tRC?nNrB+7|u_fC3QqFXSHr_S8h zYfS4nO^bJo&ncEgO0nh30avH!wiFiCM)BVw>0E)wj13A7&8W&Z@FzD`vZV6Sj(|qN zE-Ny(kQMb^)m_sEsd%R;DF{Jnf_g6Cu)Q`|b4z16!B(A@08|!L)#*3piM*c_kle6A ziM#_ZfH@?px5;5C2g_oky>ggiv&>Z{WJ!S1Bj@|Y?zmVR9_~^Ev=57E$t6jXpPFAR z9399}+fm@Vy3%-!jjFn)bw4-%VY#X$Ek89--%DVvx{!mtovuIGk_-i<2=_nP7Ac_9 z^HR#bRmyenXX0Q`oa8?ZYZZ`k-m80#vwAd8>snw-hkiq+7tVPVnK(r$ogK?O38QAS zO0{B2X8eOGfX|OC1}G>yTvMOSx8k7Y3NN)Jkm*pO_W&%cV+dT_K8!MJc~|s%eiRrA zNt+aLy_~V5w-d)nTQe`+1*oX~`lyNzT$gk$PEWmbrw2!yl~xEJ6FJx)*B&#W zRTd~_XmTF9B=>^*AjwKwC&@@Lk{zBH&zl6MyBM3Y6#IZM}~_t{lJYG?m>RP9q^bc^5f}_&3Jg%!df=&2Oswm5yLC zQU(H`FusrD9Ui0cyL~c|wzV*1sksy#rb_g&7|4$7T5*g9Yqq%C_9!QlD0eo|d$S2_)BA`j*Ur!-Yld{4|(% zQW21GirGC%Z~=4!h9Fb#G0qMIH&TW||Fxf0iFXYk9H$SpuKB{40`CM5=Q%X6iY#mo z55vXg$X~}eh)#ODTy6M&6u0%4+ywEJ62X3ly3eD6taHN*?o~No%@Y4X`WlalxzivIZ3NlB?Q@( z|7&axH9+XKPl6hEGbGj-vE2870vuI&F+3v)aa>moosMK5(KQ;L)ZS$s;I@z@smw`x z=jam;=1#fhBd}s#4s=dkw3uf8tJ23H)IN#!c$-vwG%MjEKp}c#7QfP?QgPn!j~vyHb6JJ8SQ|7BK<-`8T+mFewpkDX@^sr z-H{cuB1O2JEQY}0wB!U_1n0c_EtB{eaek(C9V6`65yVnd-d&fDH|>$CAa7(^+(#pF zSAzG>e2zUp-*1OL9iTstg9#%`;-|K|q~@oXSyE4FS}3|2mfNhrq;IAk^B}TeAdznb zI%T}7H|Y`;jQ(C|%av)|9^%FU^2>ymm;ODm^Q)Vmw;-!tzMbExJchE^7-x9pxO2Ga zKAkD*Z?;kv()!(PCkAg-Te+PGiH&Lwvo9H(uACr=k;%9T(7U~<$JEj!+xA#X50{t& zRMGLlAUFZG_v7(im2~Mi_iMSf5(KHX4cFw%k6RHL1xVlJ8q=kk?|n?s=AYH4Am{7X zazu5cC`NXz1GdB_y2*Z($RZv#>VM|8VfJ%VQRiO+aoR3MuKVu6LRGDSX)Vf0U<>zJ(A#zP z(#^{I>sT+#6};!do*)rR%Vq=us0~Wg1flI8R2`ns91(pmsc2g~w2C30J4DYh1jy?G z0nwr=_sxI^?(BwGJme|cIB-3=5|EE1pB>|D<@w+jHYQNV&IFLj#W-F;U0gJYc5*&m z>?%8U=F|v%=UYn{f`!kjTGsmW!Ke4DdjUg*gVa9(@E`s}ejGZaq-ZW?E}aCigg4RX zQ1d1^*qbXE9J2~bcHZD7F$A>jPLRe1^J9PISzFq0C9)l#^PcuZr_;94_5F#g(M22d zVP(0PPG8M+6|<%QHvN>)=vvW9@>MH_2id(*Yzh8%L(@JzYu&eRR27M0qRqpp<;bTr#|Tn0TT+WDj$^X#^dtGDyKf8tk-FkW7sW1|5gb4^2eW-Zy~7T;=5 z1(Ex=7vZgd@9%_$BeNVvMm&}2z}hxh9Ev1)8H@$mK7R2&w-ofSn9ExOv5-q`GGDdn z=AG(%l0wyZrI)Bnd|a_~(Ao}; zQ~p+8%I6lw9jfI1hd&vT7suvkO5#`+D6)rXIL1} zP&tm=QGdlmb+etuV9dY%X6VW&$8je(t_KY<{p8c(xWzcRrp>VE$(iaFz6^uE5(+ex zwN|YDPIc(u|71=et=hL6+jV+Im1Kp;KctzJ{XGmJfiC?xVHUtd`D%_Fh(Y-%o>VX{ z#uhA6FjHP73;^@=Z#&+WKQ)Y5lY3^!l{L}nWLazh`n+h9?_DRzt(MxJorYn(kJQE_0Jby6xOM1Am(>TV&fLr(|X%W&kwLLmFN zGsKLGXXlBmL(jpk!7o8+g@-C9%P_xpCuFY8Z6#GOM*}MzDpDBSX`5vi`(fTjky9~U z{#A7OK`xX>D&60=)IS0nSoVxZ+G;)=i4}{XWPYHWMn)>}Z4{PVx#gad#*~R>31U8a ztbPiXEDP4%Exc6EBYl6CyFtN6IHK($Y9&w*!&^||ySTGM`bH9?>}mWk3&+8Po`um+ z?MA><>a5=H_7izSoGD*zN&$dqAGZH%F=ja9T<&_0%sas3Y4{9YN{fr>;8T&$t5GWU zVHt7vsTYL|wKS@VOCgJB=f!jr9~9JMuz222y}OG0z0+-cC$9@PG!SAXzFbNR-0jZT znkv}#O%K#ZG5bS{BpbrBeG7PO$5>UaFWB$-$u^7<$~(5@tWqV|GN_P}eUaZo6!2oV zRX-Q$t1udV$C))he}~Dhie5yAWo3$z_m8i~{K$=AWd-ZYGbuts46^H7tIQAo`QK3( zue^s?L^g|%fFat3swN95(*sHQa5@MPq6&GK<;uy;Y2nX(rcktF7r^cy~1u=)w-V&MaPZWRv#C+XA+y zT^x$#r*>#6)*+8hmn|qhe^QoIGV8?Pl)3ko#oc7cyJXWlS(MMm@E{-VnO2_a&6Wq< zH@GPd2$<>h$amAzvfZsvuD9JQ-LJRShD6{Q8kjikOE{6C8`lsVgycK!xc%PSb?10F z-o*ce*shv?qwgy64i0az(Cr3fU^$%0;>j?>rw&h-R?hCe&0SwLcBqgEq!*~7b2ba| zJxA%cq#%Pv&m;t?UTSRWn7Y)f?UN_Dss$G^?kS`X7h<|D6D8Jg;Il6L{3SD6upHyC zFmr!^o|Wf&i_BoYeG94bNQ)lQ-D*|g0m&2Zftl$rlj4(w&&`fhbbU?^Se$4DcQZ@T zOtz+G$n>T6KNRBEX$y^iqb)2+uv_&iC~q3`ta0{{Q}7_S*-To7r$$J}k8^c+&=DkG zA*x}1wRYro;6D8M9(nE`nqcyWM(N*SLU$qWRgg&sUkw=DMbnTebmpVHsq@7}$iR0T ziMEzWBX1*gMS3JCissooO5%f%J8w>_xpU^&C2VCp??QmWtv;ZQ@nu-k5fB}uV1H+n zz7gRRY8jb5#x3D`s4odSOg;Znlb6ixE(}5hDYidB^b6c>$f|m^blS#XX8{0f%LNCDT!ww(kaF05L35%l89M z;ns>9JX#Ci0opml3~G;e<+Bh)nqEHUWsT@=#^gPjc8H5#!^M6~q?Ay+hGV&Gs?LDy)ZMT@zK(#PN z$1!m^4+1uJ_Js55b(MBy=*rLOZLxQN?U@DNU!(^N;LN{cy695OY>H`_c>iuPcT-ax zMtt8arh09-_ZJgvd^4C&W@ce>{h8NqDjljCIoaEV7kO2l(TDk+@kTyLe^q1C}8HU#w@ek{}2L>CY_ zeW>&QHn9^@nOpcT_?~BKktSzyTISDFCFW1#M$}a`{ zrfYGOUNC{6(DU$7K887mnGc#4s}ivER`G5pRd~m%nmJe1bC(ht$i5u2-EOZfsaV0)TrIdB8RD1vG z9>X!3CgUUftyl<>I=lESi%e6d2$aB+Uq@qjb+82et{hw6Aw+*7>P+Xq%;cAFGE8R>xb}Z&ti{x-z zc1tLmC*g3tT|*iYGEsRrE#XX)3Xb8?wjqhO`m}N3YNo>*JxOy8hkg3&tqKfftf$M6 zLc^EYBaf>+A9;@Cfj5W}^t0cF*I<%*lL=_&TwMss(7YpfHAnm>jEzutg z$dW`30)&D>(CI!a97{~qY)3ebR5ms-+M2rQu0(msyO$GVHyv#aGsv5?RmI`SZ#`K< zOAP*OiL=^yriB3l)hkR{ zmc)oq^&YZMmu`8!YL=^=kItt=`S4QK_EvspmvZ75TE9rGF^|!NfT-J4#1)eE(Ui33?&?_c? zrT(*U)02O3t9WJ9OGY+Zo5;GeV|uwhX&T<}6Jc%^LLk9D(&#zjGUOF=XO0;b&b76F z;wqRS&Ctn=Z!}@$=-?0RG#BBH@lz1#E}o?E=&EtNoIF7l6rs~SDw+EH+eWd|dNPrbPX1b7Lz>#hk#B zAR%;(Iyk`fXTfBHw|_VBZqlPxh`7VfZI*HM!w*MG=Xp8f;;ElqH^9Hu)Ud3si}IeN z8jEj#*fIK=i(OE*Ws27)g<2NjAyoqYS0@g)Wy-|8txli_Ajk1a>-FK&^?^NZqSTB_ zZ!urlUq_WJDlx-VK{0G>_ndtoe9VxS!&bjs@1`wmC6FuV$y2UHpWLz?y<3Es50k`H z;`*ukM1#!mb$}3x+YScx#P@G*G$Lsmp*a|bQmkYj(uC?!G>p{GGIg)JSAJ^cLe{^( z%!|Pv>5jYnuLw_KWKYC9j10>dq=p{b*PAX+j9GEHOR=AjbCen&K(rMp@DR&8Q2QQS z=lYxraV5!Dj&4}{%c5FVYw%2|`#ph$3B*h{L+o`GE{d(CDj<=4V3b5ZC5NQVWbso> zbb>cGX_zl8p#k2LInd%0qs4&eIA#t$h$p(S2Z!fBeo{tT6=oRwC)Qn?xmN2#j=qb8xK1wdX&PDgA8#Yk-H5##zR$uX^3}Et|Lbkn*Dwd1SwBic!_? zw>jaX77Pv=EzJoH1^thwo{^Bo7_=f;#gz?nUA-G8{{(H;TB0_zG(2 z5oAa_R(Zhg+IxY_>_G#In=ODY1DihBZBx+)T}#I`+Beur%e1+p;k3HYF=0Hs6P-it~30RR9Fh8UJ9K!|3j}2X_z730OWi4*t?qVdNjBgsmB7O)|oAlM++X z)II#RrBhVz%oXp9=!;8l1zbcEA8EO{ohR<@nTP#Lp;n;?!xVCs=kigq|>QG+=!;P#HffV>nFQi#eZaZU7ogA$6i85%ewKzg(Rg9=!|pLO34)zqR4gi zE>&eo&n=o{Hg=z{_P%w}_>ug=tnS!GrFgemn3NZoydxa1F9toX>@@#$C{e)nVhvRC zhmXLhAeC#L^mQ<>+KH{T?D)H4+oXnH*9$LAy^!skZ{a2sL49>UfwTRh*WQ75n_`{* zhp<)WisdwJM=a4QZQYWP9a&t|1O{n2CvmaAYc==syrgohpO9P2IzmEsB_OnlnmEeT z?n^CLf;h@F!=*JFf|ziF+R3aH5Uwn$77&mn*VXMvV3Q5zY*n?1Jz%(C@(iB`mlvOok}K6JOFMX| zOSC{NnV*h0J;)*=QvVGho(BE9M0b^w*g7c}Gz~4+-<`EoPBC~o?7+9yn}R%9g@lE@ zmF+azgQ7=Nf5%i*u6nMAnI=^`wmQ06Ntt*aG9(InpR{1Pa2K9E_SO}FfAqI75!Mk2 z)HL3GX6gpi!T%22EuJi2kzPC9_H>@8Ioq{MP&u1V!Oq^2^0&1|D7l%FPku2!t06Qc zAIf0<)XrXC&~)N*A7LF@fAwhBcBEGr7&t9~Q{o*YpzdUKlFvB5`AbU1wf-BQ<+}fP z1#yl*!|lRO8^^SVccf=Q5}Q?)@MTiVQnQ+htR)GsW~7|I?b{dpHcrPB?SiETA;!5Q zyUvkDi}JuXqV^R%HWsFXOz$8oBXvNGawGYcyV@l^k7@kKCtmHNfV~Z2YE0tacO z*{}>TKJjHfsEEJM!P!9ql#m zZuQkM4Vs#r9lakb_qLoZOG#B1J7L9d$*;oqN zcLy`TvQ2FNyw@5G3OaB-)q6hG{lgQjzbNMvFtQvwbQw36#AZsHlSF|#tEkU2PizQV z@pQVFB-{P2AQpc_RCj=sn2%-BzdIMco(- zxw68Ag;S55VEs;}IY?*J`?kk;_bgDta-8bj-9MSD@?Mekcggxe;C8yB@?pw%5C85K znq-gIf`ezX7X0o0N~z?2P7r3XlCljLd$gc=9J^gC${Dh(3$5A60>PC-#HQxK$7D&< zc*fb)r9~N&8!DQqm1ERYe(f%^=?T-n;AK(2FNTHr>j2Wr4Q=--uVEM}ix#@nd!CPIVqGV0CA+}p;Giirq!xbh0RxtLMn6iY_;dkatK znOTtFzxn9vKOYum7>&i6GB?aEO>yArT*7+2X8waZC* zKKE0;&Mbvw=lwam-F}J^LB6&yWkP*Df`r{LBIBn8Sy)2MOmbNWX2Xnan{~cGi}$CI zH`mue%L$eGGkxI^5r4SLMFjqBl$?6y`}V=vXbRa&eo#5q3h@I3kL>Sb^9a?t{I9-g zX}z&I-wea&QR3v|LL+y=8Kb1m4Cq*1(a$|QD~_yG4Tp`5;`n76gwn#s;$z0M%459= zHFAC&r~8{Ea7VwUwAY=g77}RhxG5qkixd>dpHqo@Ti5JH8;Pgca^mEkI) zf!Qtpv9swqCk5BOa@!w{-+qm9qtk6#j=nA?Zzj92a`zOsKxI&}0f6sd(5cj_s&ri( z4Y__MDOc#J7n(V~|JC@R%W*n*Mcp@=j=ezXlA4j8&T3`!I!jDFcc-=_x?zrC4svla z`95^Jxz4s|b#GVVIOeTNCLWMfrPP8^HT=*qZ@K?NzTO{@Ad`^N*`5)nf}J8CA}0Z{ za(jwBN;OJU7%4940&B327`wRiNt;1^X{msKtX!<%Jnx@WT$?U_NpWU`a_&LI+8J2D z2ibo8I=2MYBl53ei;9T`<+I^Lj6)ytEellG^a-7>*otZITR+Sux5{Zm&K~}Tu76AG z<--0lU-z>IxdDed?;q>0+Hhn%MgoF=@MUY-yR_grR1OLmx;#~uvZ#p`=Wx|oA8@3Q z#A~pO!U}qJpkt`}yno~yA1l7EU#*$eV_+CCy}Wp`y6l(jJdku{Tptku#tZSI_54#H z>rG=yfG@U;cgUFSeVET(J9aSvr%2FR?Thvt12g+`kHD2nMH)EpP4<3{h4n4iHLLmw z*b9cHc@~+_1o}S(tHp@-XOL!D4yK0I>*^RE)?g&-$8labcl?&@S~{M zh{c4ww1xK!$gygG5U9X0^9MeZ0R!ZIdP8llTWhCFl}OTK2P(f#Q`pFnTrnne&@~yM z1(}Pw_?R86Jv?W@zKrR({G$Q&!I}k^G)Yfc7tm6^)5RQf_^veGnHJHjfW)2#&81}c zJl{{hia#-~-oP29q=1R%KQPfd%q?)weOleB>o{|ATB>XLml*}!bx(>&{S6(EaoMX$ zd@fsq`_CcgxrxC@8(6UlFGVBo)S?6b$S?AIA+M?`xl0ze{sGq%qAL6Dp;4Dv@uE>6 z+a=1oMQ+6vJ%!esJb}+L+{7qN>-F&B^1sMS93hrN!usHLQx01EX zCv{$pS1=;@Zgc)2Iy3mhM15uUH}t)?YD;mN1O`bbONv;R^wN)#%R6@LdC9M~mexL3 zUK=$AJGeyTvs1JG>MLIkE4_@|1Kt1BNuKo%XcAaa44XI-b5Q%CKJ|MGU&Poub$|OC zjjHgj(|%iPhz)V#zeZRRztQBMNgrQNFU#)C^Jt6EAB_I~o42@TmTJw`5%j1zP+*o%nABxrK82tQ}W+CX1^hF5!@AVUA)j9?)#UD^j2FkVr|d)u8ev}s#t!rA<4 z+L6O*bb?Cn2QKq$sypJ3MWCQ@-WkYAOSB#VRUEk5!0;TfIRr1?X$hk zvpI;J&gDs|dY-LRXlb;!anr%~LUP^VYa^CW2FN&WP@C%p3cjBj&1Kq_pP5J;DALk({~xcl&}3q3D!(3ACj#|bzxB25}Xzy5B#BFV+E_n6|Hi{-IH zc51w0Y7Y#4DY1AR9Qhlv;wW2XrZS`=ur4TNv_Ui0r^yvRo%XY`G!vivlCpq4)T@LW z;`i9FE{_RiTiH!(pc}pW?Axb6+|>@Ao2iW0?|{_P!OLOC+2Wrqw)8)3MbDQq(ND3G zS5`(>o&7;e`NX@Vm!hYnc~imhks)1@R?gg$SJCNwfl#@zOI$Z zV^&hryTP4SF+riFQgGShy{N%dRvJZc;WN!ysJ#|F5~;7pnLH>Uio#CVQySTTzQ0^y z_=9#MA#G)-h4zhTChSYenoavDI8ve3zTZN(;d*Y^*Z43HCsF{k`z4?WorM`0jh&BY z-ICZtJ|TJyN3i>Qab#=?*aK%XSF9J@w`X&e(CPH3DHd0QPplK+8#~spWp&|Y$dbXs z!qn7c*g&7CMSKPjou$Ct>*3$Z&@OhZxL6@EvnkbylX5xR3R;S(qeUW11w@HaVW>H% zt@YvPk}LCFumPyIDxQ##_>aAcvq{p*w!ZqLa&LRZy=Ozh+kU?;&u_H$u(`;DM=qSF zkB&8eeLkb0ROh=5y+m;(kWr}-fE26(GKp-E*V@E$Akxmw&CVLWA@YF!OF@MA_-qAJ z35C@i%~CYP`E-atmBsrZZm1e6EqyIE%b)*i?>f7hYPT)=zKS%Z2#AQ%k=_KPE24Bz zlokR=3kC>LsAU#A{AOY!w5{h&P?dIHbKHT4M$625D82iIB z)*5>~d(AoKSTh*4rCKE4Ce!oBy20hCgYXmG9iHvS+MS(ZE8#b#0b+PlPV$4=KNM!V z#}87}(?_^)lY9lQhF#q&h?dR8WlT)<$kYwxdgFwFMPd5Q3>VwpvMby^(Wq}WX3gwU znjQ3dbLykXQBjun%K7i(*TDtjWV1Wp*neUqdMD9eFC3sZnPi6&3RhBT|QK@M~+o-EXg}U%aYh-u>&U^u+fvrYE(9_@`2? zhIWAgIulXHOtFdcv14a3N?>zY@gd}tX)_&1srKYnczOo+tFklS_aNbp&&d8ak&y-R znfK0mhuVUwE+X3#hFu0#S!5IQNW_vl5BK0AmmhtV#hW~CYX{Zdz00gmnG!7id* zRasbM;owmni%AW{XdknzL!kK?NNjZ8b$lyME8#UO$~VfuM*(1d{kn$t+dp%jX3hgD zYzvr?{P2riS4gj}+UR1KtzMs+Qcb@7l6(bja)WoK z=xo5FC#JrTdOw$pN8SsmJ|t6yH8PR=vjg^NUND`f!iwms9ggiV2P%xa`*25uHUcIX zE_44?uBq3w;=HQ0<}G;(&`gIvi}<@>atpXrxq<=KU3=`tDU$sz{L>4n`nLZPzX;6{ zyR7POL}Ogk*=>M+*G z?X<+Pe1F?)ugeZP_v&Ht8mh5JLqaQNlNjve+V-uV4Gv238A2`g0p{0sRAngxA4N7V z{BfLiJV*8zqUoSvvs#9~%?j(Ti}KA_k@bM=@=8`G&xQDdpw;Z_=RdZqiuB-oSXPtU zH^s|G(GWj~djqxt^z%(Au{CeQSn>|`yi_HLdHB)v-!zqmyq=doF!qYF8H8(~;CT$=(RSdX;P zT>g(ss|7VPC&$}uQVm{gh&i3WbI==#CC1`CcYl^Y=7JW`1dDx*Kr>He5rxx6DB6YB z{9bJdlET|k29SE*f_0H)+8BUcdGtO@P0Sd-r&Ku_%tcS(}Flv%7ks1vrArN*~Sh9|+NWaDKz3&T;jFGd~9kVAFKC*vSB3 zXUsm<51mNJL11#So6jv=3a`7nHahz3?`Nez6_yR#)Q&zrd2%D(h)0Akyz(qP#}#jE zfE{Ftt^XG~qGkq#1RcU#W_|&|>g^$`#nWvwGlvTG3G$5A%!$kq*O>@-zH7jJeQQRd4n%+2yKibREnUSawQ8k+I! zpO9~#IC?@beWt8AL{euXd^yWWvGX$NwOkc5@Sa^tjAB~p6=-*NcEC~3a<|vn!Rd9A z_Jo|`_CE_Et=_(CJy~&f6`v}^59Onxx?FG?V<+_$Oc$>bQ_sgiNc!IA5HHUfyGuYl zE#^crDLN{cV$H^qn9+B`C9~HM<|(ZD5V?`rcing~qR2D&I4D(!yFI}vP1Bv3bBa)+ z+cAwY@h$XA6}NpsEJYEfDOp7(un~KR)U2h2f0$qnXQi}_ps*+vsW3cLzeEEpiD@pl z^r4`xWgC^(aS|VY0o3oW;0xuozh$qpbc0dth%x~$H=9%(YtCy4Fc2JleJf&AFnly0 z{WTQMgUxuTd_FKVlpQ~q$+z?c)X+Jvs@*<@vJdyI51yd}XVhbzRvdLeW2Hq<1HtQHaqx{DzDFRjO4 zXF7kl@EPIM&x#SONgcKE@)E22dW-B?V(g7KE9d&6)^ncyb@vN_xltLT%mNm*u`;J_ zj8S`~nx1W`J1Gs4%m=14+NPdxhZc?NWCa}^adye8^Qror+i(a<*yEHDX(w$Vt~e3@@{$c##bxK;EiD?WaK@2$<}}X+m%L%8fGDjL?-5Y~9ny^ebZGD*npli_17BjkMUY zb=H}w-7ua2CF{kSWCy67{N$t(8OoSqAxsWmm6X#@OYz5^UCK%-!ObD0v7FU$x$w`) zcamiJ#S#s~M6BU!0K29;eys4%g>Md7%qUKE|Pu;DLsbjdl*I{MQQ{< z7*S>Ie5>?39>v7xC}y?h2Y))c16v7^dDc@6IC8v8ZrN3FMy+g+;xH9G5 z2CCniW#P-`qFk$-wl|~top34 zVj&gAyGrlpdEib6Ud??|z!S-U0st+jUTU8{Qo(6+c}de|;b6Rm?|eVXQ?f&9i04@X z^Du`K*t`$H?G@0ao50(v#fFo%l86eEkzm>|upBO>r(uy9e%$Z!qLojbSIi>Y~r0XgZHYUiU=hO8Rh`AXWE6siVa zE=X7R7U)>W%2v4=`V~2*sno8ObnLZ%*Hnj{igO)iIBTE6`a{D+I|dqO2lqa!`*^N% z@rChz)P?g3gM=T)=(1TAz7U2u;q{lB)}WZq2)oKr2>~E#G3jBSb0RbvIyG{(y1%cK zCT`b@SD<>P&J&g?t!|Y~3GXsfo+emU2S=y)x(fgf)EH=(uibH@`9986s?mzxm*OMX z7Xc;dSR-VNz=&bReCGtccA0!|)bZ8?LlggE2C|$EJu`LOTcYcRnP(?A#s#L&r|W_X z=`9moUX%X7i`rxh3JnEJ5B$q+MhIyoG4eZv{*A9u1*|06mv)j_399F7ZB%}z7n?E7t8MMs#1rRcgYr_Y;TTPtc*Xu~vG(CY zP0`)0<0d_q@2tKAE4Y^KlQ2dwJ>M70nmj9Txux4k$ zy_Ew(t}{%SfD<*?mq+pubP? zrVm;vJwI8DyQ2B=HPLW;T{2eMUf*6KKR#M`u#`~pW|GJ4T*g6i<|&fjyjik^z{+A% zeJn0dmrLv{`C?;}>prLA>ep5FMeOjOv9fkKQyx3BM#dN+2S}i*#%)Db|4d1XldF$S z={uN7)`$M01J$cyRLj*;&s3hkLn2P0D0TIVhNY?D`ieVBhEw+CiFxn=wUJu+62cmH z3bdG%d_uZpAlSjnI1L(_w+P8a04)v5cKbQS#_jx#*MjPu!KTLNsMC3{@2-aw4+OSF z327^y6N4CUoBxhgg19!s5+r#nC209#rdzjXfFr&Y;4p@OI^eO;(4v@2okk-iIQ_g~ za~SW}#MoHkhmb2fm4aCz$&S zc|&e<@6*sQ4C`q>er4df&^nfFTO-l**bY`$>4%1`tS^cSAnw|0bI4n+(_icD48)&5 zRvFzHEv{J30C!ZT<}#$@0Xf1`_qytRg6mX+gE2ee6|xvn4~ux06NAx)KBk|pldS2~ zY-4xm(3|CSQJn8hN?MPjgYUa{WoaCv=LqmrMm?_6>lKz5vGi*S zzo(9?HXv>0s5|D@g+b;>AfBJ2WUYjN&e^O(tz{~zbO#cK4$f;37Lmen^!@eqw`pjA zqEQ(%Uz@*~oo()iSaMqLwiC8KI|Uea$gP;B;gLlXVKHyv<#| zT=X!;na`oi+O5tcn+IQ3Fn&`^7(!1#0@FT^azb0)xVd^vK|>%Y8L8mG9V8kIFxqA^ zz-Rd`v1v~tH@`)DZ*H9gZ2e(F_0e@axZG4WA3A6-Pb$II`<{9DZ7?mZ*$cgPz{Xh0 zCNe*pKoOp|1VVn7Z=feTpk=dkcW<+i{T_tO7I|IN%nn*HSe8+nR;uVLDwgJTxO|w8 z&53%Z*<|+SiDsk@EY+tdztUYmP}f%buPegkXt9;D$DrU`H*eG%}|~A0W$rroVmxC{_Gzv46abJ6-S!p1Iwh;qx9ZmuHI9u00Bd z!6L`w23-r_b8Fbxt>DQu6P*EV45yTx;XoNedmH)@Oc$SF5J@-$zGZm;29;aMx`EQd zSQPULxgffz$yX-_o5bH{Ii#f^kiR{th`)fU1$|PV*O@-1~HK)Tkxu>?$^7B-K zYe4nAXz1@W4oA%CRgO?ZMb8)~&ENlmP7+$dp4bzmi(X1%{k_`(ZytJi2Z0ipoUgr1 z%GkPX+`fwsUB2k(92i)?Ul_#>F@gYJwo&&R20EI{#KO~JKo;!DSzfi>vT$@CS#5Ra z6U8RO&l^UX8tt7Mc-J9gpfvkZEPY&gILI0L!ohcKgA9Yd+})7QJU(At`*cLov~aXv9r<@Dc#jAd1E`Q791XR(a`n+wqNF$?fL>5?(|(b<~%X zbf!tHq}e4M%}^@k87uNEOKhb*==9w`p{nV|50pgeZ$d+VvNaJkM$KwY{>(n<#;L1o z1gek?_2dc?9<-IVRdu`^GCHbQ|I?`jcD@a=$IchXb_N7;W%8+x< z67-bIQU=-VIvqcWKVfM~wh$x#?U^PXCMi(IPS35^AM-4>1o@uI^Fsn13{<8)qWYS& zIXeMMyJBvM2Mw&h`o^TBv6x{&aw-aUeeh2D;PqR>_x(|$C{LdHNBmJr+YYi#aZ>kF zyinf`)f{|X_qYqG%;LZkj>UUl z-XCS-u=|OAUgApNaVQjaaoVQ#$g!sA1{Ha|k<9NN{JxHVMkQ%mn@m0S#eW*Y@~J1e z2-|XHlDV*Zq|?7doDz9>Y2jOkEe#1XQvlM=TVS2tRiQuVz*y6VhD z#LjV5cJKwWn{TOOX`Nzosp&xnq5Vkw>;}nSD(dPqpqhoQfFGm=8t-~yW;Uldat+i) zNttiJYqeYzJcBU|NR1hutkc_lu4m*<=?YZ#wgz1OW%lg>Eq;o6|?{>&g* zve=7o?kJ#%!~C;u@Tssj8ZpMrJPVjY3$}oUL*cyhg<&z zOkq~O^j!$i8*j99wX5cAfl4#4&uYVXmkkF%MWl*DOYzCL!m?+R#`zsgW{Gvw{Ja}5 zVtA*hK1>}dBl3^7_CW1GVb+qFuZrr!wrsOT7Hc@0?ONZWosVpoAJK#wHbUz*L7qz? zMcNSSq=R$$RHn=Yjv+>iHSw`S-J;5kb#B9RBEGdWZ_#i%{zGfL9x2}4KD`reCP~co z%NL>qK6=Y>#35P9NQ1hmZA`;_OL(IsbUqa1a*ohosOyo*H)^kL4j_Ct)2+#?E%j-A zBw;xcv?$0Vsudx_v@TLvEu$*c1ZcXh>U~aS%MC0eY8klzLF4~gjs2nT19j&APh75J zRiS#1|2w`{hyI^8|B{mZCocc@`F|_%-#YyJgZOV9{vX!i;NnvLmzsG8|2nFNG7XL1 MQ)6wE*6Yy!0W$V@5C8xG diff --git a/backend/seed_data/assets/csesoc_logo.png b/backend/seed_data/assets/csesoc_logo.png deleted file mode 100644 index 847d441db694814ccda089df104f090eb725c90b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12285 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

yK8n@QWKa6w4sic& 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

<=;fj$;z1H8ZuCHZcG(Bxyml-}u@7JQM?B+9 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 DEB1(a diff --git a/backend/seed_data/src/main.rs b/backend/seed_data/src/main.rs deleted file mode 100644 index feb583400..000000000 --- a/backend/seed_data/src/main.rs +++ /dev/null @@ -1,8 +0,0 @@ -mod seed; - -use dotenv; - -fn main() { - dotenv::dotenv().ok(); - seed::seed(); -} diff --git a/backend/seed_data/src/seed.rs b/backend/seed_data/src/seed.rs deleted file mode 100644 index f542faa2f..000000000 --- a/backend/seed_data/src/seed.rs +++ /dev/null @@ -1,311 +0,0 @@ -#![allow(unused_variables)] - -use backend::database::models::*; -use backend::database::schema::{AdminLevel, ApplicationStatus, UserGender}; -use backend::images::{save_image, try_decode_bytes}; -use chrono::naive::NaiveDate; -use diesel::pg::PgConnection; -use diesel::prelude::*; -use std::env; - -pub fn establish_connection() -> PgConnection { - let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set"); - PgConnection::establish(&database_url).expect(&format!("Error connecting to {}", database_url)) -} - -pub fn seed() { - println!("SEEDING\n"); - - let connection = establish_connection(); - let users = vec![ - NewUser { - email: "shrey.somaiya@gmail.com".to_string(), - zid: "z5257343".to_string(), - display_name: "Shrey Somaiya".to_string(), - degree_name: "B. CompSci".to_string(), - degree_starting_year: 2019, - gender: UserGender::Unspecified, - pronouns: "they/them".to_string(), - superuser: true, - }, - NewUser { - email: "fake.user@gmail.com".to_string(), - zid: "z1234567".to_string(), - display_name: "Fake User".to_string(), - degree_name: "B. CompSci".to_string(), - degree_starting_year: 2019, - gender: UserGender::Unspecified, - pronouns: "".to_string(), - superuser: false, - }, - NewUser { - email: "michael.gribben@gmail.com".to_string(), - zid: "z5259232".to_string(), - display_name: "Michael Gribben".to_string(), - degree_name: "B. Eng (Software)".to_string(), - degree_starting_year: 2019, - gender: UserGender::Male, - pronouns: "he/him".to_string(), - superuser: false, - }, - NewUser { - email: "giuliana.debellis@gmail.com".to_string(), - zid: "z5259232".to_string(), - display_name: "Giuliana Debellis".to_string(), - degree_name: "B. CompSci".to_string(), - degree_starting_year: 2020, - gender: UserGender::Female, - pronouns: "she/her".to_string(), - superuser: false, - }, - NewUser { - email: "lachlan.ting@gmail.com".to_string(), - zid: "z5264855".to_string(), - display_name: "Lachlan Ting".to_string(), - degree_name: "B. CompSci".to_string(), - degree_starting_year: 2019, - gender: UserGender::Male, - pronouns: "he/him".to_string(), - superuser: false, - }, - NewUser { - email: "hayes.choy@gmail.com".to_string(), - zid: "z528816".to_string(), - display_name: "Hayes Choi".to_string(), - degree_name: "B. CompSci".to_string(), - degree_starting_year: 2020, - gender: UserGender::Male, - pronouns: "he/him".to_string(), - superuser: false, - }, - NewUser { - email: "clarence.feng@gmail.com".to_string(), - zid: "z5260633".to_string(), - display_name: "Clarence Feng".to_string(), - degree_name: "B. CompSci".to_string(), - degree_starting_year: 2020, - gender: UserGender::Male, - pronouns: "he/him".to_string(), - superuser: false, - }, - ]; - - // add all users - for user in &users { - user.insert(&connection) - .expect(&format!("Failed to insert user {}.", user.display_name)); - } - println!("... Added {} users\n", users.len()); - - // create two organisations - let csesoc_org_logo_id = "d6b7b23d-064b-40f2-9b73-9a4cd32ee9c6"; - let degrees_org_logo_id = "adebf7f3-aa1e-4712-b5ca-051430bfaf8e"; - let csesoc_org_logo = try_decode_bytes(std::fs::read("./assets/csesoc_logo.png").unwrap()) - .expect("./assets/csesoc_logo.png missing!"); - let degrees_org_logo = try_decode_bytes(std::fs::read("./assets/180DC.png").unwrap()) - .expect("./assets/180DC.png missing!"); - save_image( - csesoc_org_logo, - backend::images::ImageLocation::ORGANISATIONS, - csesoc_org_logo_id, - ) - .expect("Failed saving CSESoc Logo"); - save_image( - degrees_org_logo, - backend::images::ImageLocation::ORGANISATIONS, - degrees_org_logo_id, - ) - .expect("Failed saving 180DC Logo"); - - let orgs = vec![ - NewOrganisation { - name: "CSESoc UNSW".to_string(), - logo: Some(csesoc_org_logo_id.to_string()), - }, - NewOrganisation { - name: "180 Degrees Consulting".to_string(), - logo: Some(degrees_org_logo_id.to_string()), - }, - ]; - - for org in &orgs { - org.insert(&connection) - .expect(&format!("Failed to insert org {}.", org.name)); - } - - assert!(Organisation::get_all(&connection).len() == 2); - - println!("... Added {} organizations\n", orgs.len()); - // make giuliana the admin of csesoc - - let giuliana_user = User::get_from_email(&connection, "giuliana.debellis@gmail.com") - .expect("Failed to get giuliana user from email"); - - let csesoc_org = - Organisation::find_by_name(&connection, "CSESoc UNSW").expect("csesoc should exist"); - - let giuliana_csesoc_admin = NewOrganisationUser { - user_id: giuliana_user.id, - organisation_id: csesoc_org.id, - admin_level: AdminLevel::Admin, - } - .insert(&connection) - .expect("Failed to insert giuliana as admin"); - - println!("... Adding guiuliana as csesoc admin\n"); - - // make clarence a director of csesoc - let clarence_user = User::get_from_email(&connection, "clarence.feng@gmail.com") - .expect("Failed to get giuliana user from email"); - - let clarence_csesoc_director = NewOrganisationUser { - user_id: clarence_user.id, - organisation_id: csesoc_org.id, - admin_level: AdminLevel::Director, - } - .insert(&connection) - .expect("failed to insert org user clarence"); - - println!("... Adding clarence as csesoc director\n"); - // create peer mentoring campaign for csesoc - - let peer_mentoring_logo_id = "523fde49-027a-4fc8-b296-aaefe9e215d6"; - let peer_mentoring_logo = - try_decode_bytes(std::fs::read("./assets/csesoc_peer_mentoring.jpg").unwrap()) - .expect("./assets/csesoc_peer_mentoring.jpg missing!"); - save_image( - peer_mentoring_logo, - backend::images::ImageLocation::CAMPAIGNS, - peer_mentoring_logo_id, - ) - .expect("Failed saving Peer Mentoring Logo"); - - let new_campaign = NewCampaign { - name: "2022 Peer Mentor Recruitment".to_string(), - description: "Peer mentors are an important part of CSESoc and university life at UNSW. We are looking for enthusiastic students who are passionate about helping first-year students, gaining leadership experience, communication skills, some resume-worthy additions, and having a lot of fun in the upcoming term (Term 1, 2022)! 🎉".to_string(), - organisation_id: csesoc_org.id, - starts_at: NaiveDate::from_ymd_opt(2022, 1, 1).unwrap().and_hms_opt(10, 00, 00).unwrap(), - ends_at: NaiveDate::from_ymd_opt(2022, 2, 20).unwrap().and_hms_opt(23, 59, 59).unwrap(), - cover_image: Some(peer_mentoring_logo_id.to_string()), - published: true, - }.insert(&connection).expect("failed to insert new campaign"); - - println!("... Creating peer mentoring campaign\n"); - - let mentor_role = RoleUpdate { - campaign_id: new_campaign.id, - name: "Peer Mentor".to_string(), - description: Some("help students 5head".to_string()), - min_available: 70, - max_available: 100, - finalised: false, - } - .insert(&connection) - .expect("Failed to insert Peer Mentor role"); - - let senior_mentor_role = RoleUpdate { - campaign_id: new_campaign.id, - name: "Senior Mentor".to_string(), - description: Some("help with organisation".to_string()), - min_available: 1, - max_available: 3, - finalised: false, - } - .insert(&connection) - .expect("Failed to insert senior mentor role"); - - println!("... Creating peer mentor and senior mentor role\n"); - // attatch two questions two senior mentor role - let question_one = NewQuestion { - title: "What is the meaning of life?".to_string(), - max_bytes: 100, - role_ids: vec![senior_mentor_role.id], - required: false, - description: Some("Please ensure to go into great detail!".to_string()), - } - .insert(&connection) - .expect("Failed to insert question"); - - let question_two = NewQuestion { - title: "Why do you want to be a Peer Mentor".to_string(), - max_bytes: 300, - role_ids: vec![senior_mentor_role.id, mentor_role.id], - required: true, - description: Some("Please explain why you would like to be a peer mentor!".to_string()), - } - .insert(&connection) - .expect("Failed to insert question"); - - println!("... Creating senior mentor questions\n"); - // hayes choy wants to apply for the senior peer mentor role - - let application = NewApplication { - role_id: senior_mentor_role.id, - user_id: User::get_from_email(&connection, "hayes.choy@gmail.com") - .unwrap() - .id, - status: ApplicationStatus::Pending, - private_status: ApplicationStatus::Pending, - } - .insert(&connection) - .expect("Failed to insert application"); - - let application = NewApplication { - role_id: senior_mentor_role.id, - user_id: User::get_from_email(&connection, "shrey.somaiya@gmail.com") - .unwrap() - .id, - status: ApplicationStatus::Pending, - private_status: ApplicationStatus::Pending, - } - .insert(&connection) - .expect("Failed to insert application"); - - println!("... Creating hayes application\n"); - - // create answers to question one - let hayes_qn_one_answer = NewAnswer { - question_id: question_one.id, - application_id: application.id, - description: "42".to_string(), - } - .insert(&connection) - .expect("Failed to insert answer"); - - println!("... Creating hayes answer to question one\n"); - // lets create a rating for hayes from Giuliana - - let hayes_rating_from_giuliana = NewRating { - application_id: application.id, - rater_user_id: giuliana_csesoc_admin.user_id, - rating: 0, - } - .insert(&connection) - .expect("Failed to insert rating"); - - let hayes_rating_from_clarence = NewRating { - application_id: application.id, - rater_user_id: clarence_csesoc_director.user_id, - rating: 5, - } - .insert(&connection) - .expect("Failed to insert rating"); - - let hayes_comment_from_giuliana = NewComment { - application_id: application.id, - commenter_user_id: giuliana_csesoc_admin.user_id, - description: "bad answers".to_string(), - } - .insert(&connection) - .expect("Failed to insert comment"); - - let hayes_comment_from_clarence = NewComment { - application_id: application.id, - commenter_user_id: clarence_csesoc_director.user_id, - description: "love this guy <3".to_string(), - } - .insert(&connection) - .expect("Failed to insert comment"); - - println!("... Creating hayes comments and ratings\n"); -} diff --git a/backend/server/src/Cargo.lock b/backend/server/src/Cargo.lock deleted file mode 100644 index df30c94f9..000000000 --- a/backend/server/src/Cargo.lock +++ /dev/null @@ -1,2078 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "aho-corasick" -version = "0.7.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" -dependencies = [ - "memchr", -] - -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - -[[package]] -name = "async-stream" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "171374e7e3b2504e0e5236e3b59260560f9fe94bfe9ac39ba5e4e929c5590625" -dependencies = [ - "async-stream-impl", - "futures-core", -] - -[[package]] -name = "async-stream-impl" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "648ed8c8d2ce5409ccd57453d9d1b214b342a0d69376a6feda1fd6cae3299308" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "async-trait" -version = "0.1.51" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44318e776df68115a881de9a8fd1b9e53368d7a4a5ce4cc48517da3393233a5e" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "atomic" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b88d82667eca772c4aa12f0f1348b3ae643424c8876448f3f7bd5787032e234c" -dependencies = [ - "autocfg", -] - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi", -] - -[[package]] -name = "autocfg" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" - -[[package]] -name = "backend" -version = "0.1.0" -dependencies = [ - "chrono", - "diesel", - "diesel-derive-enum", - "dotenv", - "dotenv_codegen", - "jsonwebtoken", - "reqwest", - "rocket", - "rocket_cors", - "rocket_sync_db_pools", - "serde", - "serde_json", -] - -[[package]] -name = "base-x" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4521f3e3d031370679b3b140beb36dfe4801b09ac77e30c61941f97df3ef28b" - -[[package]] -name = "base64" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" - -[[package]] -name = "base64" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" - -[[package]] -name = "binascii" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "383d29d513d8764dcdc42ea295d979eb99c3c9f00607b3692cf68a431f7dca72" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bumpalo" -version = "3.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c" - -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "bytes" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" - -[[package]] -name = "cc" -version = "1.0.72" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chrono" -version = "0.4.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" -dependencies = [ - "libc", - "num-integer", - "num-traits", - "serde", - "time 0.1.43", - "winapi", -] - -[[package]] -name = "const_fn" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f92cfa0fd5690b3cf8c1ef2cabbd9b7ef22fa53cf5e1f92b05103f6d5d1cf6e7" - -[[package]] -name = "cookie" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f1c7727e460397e56abc4bddc1d49e07a1ad78fc98eb2e1c8f032a58a2f80d" -dependencies = [ - "percent-encoding", - "time 0.2.27", - "version_check", -] - -[[package]] -name = "core-foundation" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" - -[[package]] -name = "devise" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c7580b072f1c8476148f16e0a0d5dedddab787da98d86c5082c5e9ed8ab595" -dependencies = [ - "devise_codegen", - "devise_core", -] - -[[package]] -name = "devise_codegen" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "123c73e7a6e51b05c75fe1a1b2f4e241399ea5740ed810b0e3e6cacd9db5e7b2" -dependencies = [ - "devise_core", - "quote", -] - -[[package]] -name = "devise_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841ef46f4787d9097405cac4e70fb8644fc037b526e8c14054247c0263c400d0" -dependencies = [ - "bitflags", - "proc-macro2", - "proc-macro2-diagnostics", - "quote", - "syn", -] - -[[package]] -name = "diesel" -version = "1.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b28135ecf6b7d446b43e27e225622a038cc4e2930a1022f51cdb97ada19b8e4d" -dependencies = [ - "bitflags", - "byteorder", - "chrono", - "diesel_derives", - "pq-sys", - "r2d2", -] - -[[package]] -name = "diesel-derive-enum" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70806b70be328e646f243680a3fc93b3cfdd6db373faa5110660a5dd5af243bc" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "diesel_derives" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45f5098f628d02a7a0f68ddba586fb61e80edec3bdc1be3b921f4ceec60858d3" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "discard" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" - -[[package]] -name = "dotenv" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" - -[[package]] -name = "dotenv_codegen" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56966279c10e4f8ee8c22123a15ed74e7c8150b658b26c619c53f4a56eb4a8aa" -dependencies = [ - "dotenv_codegen_implementation", - "proc-macro-hack", -] - -[[package]] -name = "dotenv_codegen_implementation" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e737a3522cd45f6adc19b644ce43ef53e1e9045f2d2de425c1f468abd4cf33" -dependencies = [ - "dotenv", - "proc-macro-hack", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "either" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" - -[[package]] -name = "encoding_rs" -version = "0.8.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a74ea89a0a1b98f6332de42c95baff457ada66d1cb4030f9ff151b2041a1c746" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "figment" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "790b4292c72618abbab50f787a477014fe15634f96291de45672ce46afe122df" -dependencies = [ - "atomic", - "pear", - "serde", - "toml", - "uncased", - "version_check", -] - -[[package]] -name = "fnv" -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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" -dependencies = [ - "matches", - "percent-encoding", -] - -[[package]] -name = "futures" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd0210d8c325c245ff06fd95a3b13689a1a276ac8cfa8e8720cb840bfb84b9e" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fc8cd39e3dbf865f7340dce6a2d401d24fd37c6fe6c4f0ee0de8bfca2252d27" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "629316e42fe7c2a0b9a65b47d159ceaa5453ab14e8f0a3c5eedbb8cd55b4a445" - -[[package]] -name = "futures-executor" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b808bf53348a36cab739d7e04755909b9fcaaa69b7d7e588b37b6ec62704c97" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e481354db6b5c353246ccf6a728b0c5511d752c08da7260546fc0933869daa11" - -[[package]] -name = "futures-macro" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a89f17b21645bc4ed773c69af9c9a0effd4a3f1a3876eadd453469f8854e7fdd" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "futures-sink" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "996c6442437b62d21a32cd9906f9c41e7dc1e19a9579843fad948696769305af" - -[[package]] -name = "futures-task" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dabf1872aaab32c886832f2276d2f5399887e2bd613698a02359e4ea83f8de12" - -[[package]] -name = "futures-util" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d22213122356472061ac0f1ab2cee28d2bac8491410fd68c2af53d1cedb83e" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "generator" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1d9279ca822891c1a4dae06d185612cf8fc6acfe5dff37781b41297811b12ee" -dependencies = [ - "cc", - "libc", - "log", - "rustversion", - "winapi", -] - -[[package]] -name = "getrandom" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "glob" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" - -[[package]] -name = "h2" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fd819562fcebdac5afc5c113c3ec36f902840b70fd4fc458799c8ce4607ae55" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" - -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "http" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1323096b05d41827dadeaee54c9981958c0f94e670bc94ed80037d1a7b8b186b" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6" -dependencies = [ - "bytes", - "http", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503" - -[[package]] -name = "httpdate" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" - -[[package]] -name = "hyper" -version = "0.14.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436ec0091e4f20e655156a30a0df3770fe2900aa301e548e08446ec794b6953c" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "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 = "idna" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "indexmap" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" -dependencies = [ - "autocfg", - "hashbrown", - "serde", -] - -[[package]] -name = "inlinable_string" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3094308123a0e9fd59659ce45e22de9f53fc1d2ac6e1feb9fef988e4f76cad77" - -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "ipnet" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f2d64f2edebec4ce84ad108148e67e1064789bee435edc5b60ad398714a3a9" - -[[package]] -name = "itoa" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" - -[[package]] -name = "js-sys" -version = "0.3.55" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "jsonwebtoken" -version = "7.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afabcc15e437a6484fc4f12d0fd63068fe457bf93f1c148d3d9649c60b103f32" -dependencies = [ - "base64 0.12.3", - "pem", - "ring", - "serde", - "serde_json", - "simple_asn1", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98a04dce437184842841303488f70d0188c5f51437d2a834dc097eafa909a01" - -[[package]] -name = "lock_api" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" -dependencies = [ - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "loom" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edc5c7d328e32cc4954e8e01193d7f0ef5ab257b5090b70a964e099a36034309" -dependencies = [ - "cfg-if", - "generator", - "scoped-tls", - "serde", - "serde_json", - "tracing", - "tracing-subscriber", -] - -[[package]] -name = "matchers" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" -dependencies = [ - "regex-automata", -] - -[[package]] -name = "matches" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" - -[[package]] -name = "memchr" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" - -[[package]] -name = "mime" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" - -[[package]] -name = "mio" -version = "0.7.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc" -dependencies = [ - "libc", - "log", - "miow", - "ntapi", - "winapi", -] - -[[package]] -name = "miow" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" -dependencies = [ - "winapi", -] - -[[package]] -name = "multer" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "408327e2999b839cd1af003fc01b2019a6c10a1361769542203f6fedc5179680" -dependencies = [ - "bytes", - "encoding_rs", - "futures-util", - "http", - "httparse", - "log", - "mime", - "spin 0.9.2", - "tokio", - "tokio-util", - "twoway", - "version_check", -] - -[[package]] -name = "native-tls" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48ba9f7719b5a0f42f338907614285fb5fd70e53858141f69898a1fb7203b24d" -dependencies = [ - "lazy_static", - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - -[[package]] -name = "ntapi" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" -dependencies = [ - "winapi", -] - -[[package]] -name = "num-bigint" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-integer" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" -dependencies = [ - "autocfg", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "once_cell" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" - -[[package]] -name = "openssl" -version = "0.10.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95" -dependencies = [ - "bitflags", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-sys", -] - -[[package]] -name = "openssl-probe" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a" - -[[package]] -name = "openssl-sys" -version = "0.9.71" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7df13d165e607909b363a4757a6f133f8a818a74e9d3a98d09c6128e15fa4c73" -dependencies = [ - "autocfg", - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" -dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall", - "smallvec", - "winapi", -] - -[[package]] -name = "pear" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e44241c5e4c868e3eaa78b7c1848cadd6344ed4f54d029832d32b415a58702" -dependencies = [ - "inlinable_string", - "pear_codegen", - "yansi", -] - -[[package]] -name = "pear_codegen" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82a5ca643c2303ecb740d506539deba189e16f2754040a42901cd8105d0282d0" -dependencies = [ - "proc-macro2", - "proc-macro2-diagnostics", - "quote", - "syn", -] - -[[package]] -name = "pem" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd56cbd21fea48d0c440b41cd69c589faacade08c992d9a54e471b79d0fd13eb" -dependencies = [ - "base64 0.13.0", - "once_cell", - "regex", -] - -[[package]] -name = "percent-encoding" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" - -[[package]] -name = "pin-project-lite" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkg-config" -version = "0.3.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1a3ea4f0dd7f1f3e512cf97bf100819aa547f36a6eccac8dbaae839eb92363e" - -[[package]] -name = "ppv-lite86" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba" - -[[package]] -name = "pq-sys" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ac25eee5a0582f45a67e837e350d784e7003bd29a5f460796772061ca49ffda" -dependencies = [ - "vcpkg", -] - -[[package]] -name = "proc-macro-hack" -version = "0.5.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" - -[[package]] -name = "proc-macro2" -version = "1.0.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb37d2df5df740e582f28f8560cf425f52bb267d872fe58358eadb554909f07a" -dependencies = [ - "unicode-xid", -] - -[[package]] -name = "proc-macro2-diagnostics" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bf29726d67464d49fa6224a1d07936a8c08bb3fba727c7493f6cf1616fdaada" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "version_check", - "yansi", -] - -[[package]] -name = "quote" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "r2d2" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "545c5bc2b880973c9c10e4067418407a0ccaa3091781d1671d46eb35107cb26f" -dependencies = [ - "log", - "parking_lot", - "scheduled-thread-pool", -] - -[[package]] -name = "rand" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", - "rand_hc", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rand_hc" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" -dependencies = [ - "rand_core", -] - -[[package]] -name = "redox_syscall" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" -dependencies = [ - "bitflags", -] - -[[package]] -name = "ref-cast" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "300f2a835d808734ee295d45007adacb9ebb29dd3ae2424acfa17930cae541da" -dependencies = [ - "ref-cast-impl", -] - -[[package]] -name = "ref-cast-impl" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c38e3aecd2b21cb3959637b883bb3714bc7e43f0268b9a29d3743ee3e55cdd2" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "regex" -version = "1.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.6.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" - -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - -[[package]] -name = "reqwest" -version = "0.11.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bea77bc708afa10e59905c3d4af7c8fd43c9214251673095ff8b14345fcbc5" -dependencies = [ - "base64 0.13.0", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "http", - "http-body", - "hyper", - "hyper-tls", - "ipnet", - "js-sys", - "lazy_static", - "log", - "mime", - "native-tls", - "percent-encoding", - "pin-project-lite", - "serde", - "serde_json", - "serde_urlencoded", - "tokio", - "tokio-native-tls", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "winreg", -] - -[[package]] -name = "ring" -version = "0.16.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" -dependencies = [ - "cc", - "libc", - "once_cell", - "spin 0.5.2", - "untrusted", - "web-sys", - "winapi", -] - -[[package]] -name = "rocket" -version = "0.5.0-rc.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a71c18c42a0eb15bf3816831caf0dad11e7966f2a41aaf486a701979c4dd1f2" -dependencies = [ - "async-stream", - "async-trait", - "atomic", - "atty", - "binascii", - "bytes", - "either", - "figment", - "futures", - "indexmap", - "log", - "memchr", - "multer", - "num_cpus", - "parking_lot", - "pin-project-lite", - "rand", - "ref-cast", - "rocket_codegen", - "rocket_http", - "serde", - "serde_json", - "state", - "tempfile", - "time 0.2.27", - "tokio", - "tokio-stream", - "tokio-util", - "ubyte", - "version_check", - "yansi", -] - -[[package]] -name = "rocket_codegen" -version = "0.5.0-rc.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66f5fa462f7eb958bba8710c17c5d774bbbd59809fa76fb1957af7e545aea8bb" -dependencies = [ - "devise", - "glob", - "indexmap", - "proc-macro2", - "quote", - "rocket_http", - "syn", - "unicode-xid", -] - -[[package]] -name = "rocket_cors" -version = "0.5.2" -source = "git+https://github.com/lawliet89/rocket_cors?branch=master#2ec5b3e0918c5ed634baeec3d1948f096f3c534d" -dependencies = [ - "log", - "regex", - "rocket", - "serde", - "serde_derive", - "unicase", - "unicase_serde", - "url", -] - -[[package]] -name = "rocket_http" -version = "0.5.0-rc.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23c8b7d512d2fcac2316ebe590cde67573844b99e6cc9ee0f53375fa16e25ebd" -dependencies = [ - "cookie", - "either", - "http", - "hyper", - "indexmap", - "log", - "memchr", - "mime", - "parking_lot", - "pear", - "percent-encoding", - "pin-project-lite", - "ref-cast", - "serde", - "smallvec", - "stable-pattern", - "state", - "time 0.2.27", - "tokio", - "uncased", -] - -[[package]] -name = "rocket_sync_db_pools" -version = "0.1.0-rc.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38cfdfebd552d075c368e641c88a5cd6ce1c58c5c710548aeb777abb48830f4b" -dependencies = [ - "diesel", - "r2d2", - "rocket", - "rocket_sync_db_pools_codegen", - "serde", - "tokio", -] - -[[package]] -name = "rocket_sync_db_pools_codegen" -version = "0.1.0-rc.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267808c094db5366e1d8925aaf9f2ce05ff9b3bd92cb18c7040a1fe219c2e25" -dependencies = [ - "devise", - "quote", -] - -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver", -] - -[[package]] -name = "rustversion" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" - -[[package]] -name = "ryu" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c9613b5a66ab9ba26415184cfc41156594925a9cf3a2057e57f31ff145f6568" - -[[package]] -name = "schannel" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" -dependencies = [ - "lazy_static", - "winapi", -] - -[[package]] -name = "scheduled-thread-pool" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc6f74fd1204073fa02d5d5d68bec8021be4c38690b61264b2fdb48083d0e7d7" -dependencies = [ - "parking_lot", -] - -[[package]] -name = "scoped-tls" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "security-framework" -version = "2.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525bc1abfda2e1998d152c45cf13e696f76d0a4972310b22fac1658b05df7c87" -dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9dd14d83160b528b7bfd66439110573efcfbe281b17fc2ca9f39f550d619c7e" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - -[[package]] -name = "serde" -version = "1.0.130" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.130" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.72" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0ffa0837f2dfa6fb90868c2b5468cad482e175f7dad97e7421951e663f2b527" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sha1" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" - -[[package]] -name = "sharded-slab" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "signal-hook-registry" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" -dependencies = [ - "libc", -] - -[[package]] -name = "simple_asn1" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692ca13de57ce0613a363c8c2f1de925adebc81b04c923ac60c5488bb44abe4b" -dependencies = [ - "chrono", - "num-bigint", - "num-traits", -] - -[[package]] -name = "slab" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" - -[[package]] -name = "smallvec" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" - -[[package]] -name = "socket2" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dc90fe6c7be1a323296982db1836d1ea9e47b6839496dde9a541bc496df3516" -dependencies = [ - "libc", - "winapi", -] - -[[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.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "511254be0c5bcf062b019a6c89c01a664aa359ded62f78aa72c6fc137c0590e5" - -[[package]] -name = "stable-pattern" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4564168c00635f88eaed410d5efa8131afa8d8699a612c80c455a0ba05c21045" -dependencies = [ - "memchr", -] - -[[package]] -name = "standback" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff" -dependencies = [ - "version_check", -] - -[[package]] -name = "state" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cf4f5369e6d3044b5e365c9690f451516ac8f0954084622b49ea3fde2f6de5" -dependencies = [ - "loom", -] - -[[package]] -name = "stdweb" -version = "0.4.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5" -dependencies = [ - "discard", - "rustc_version", - "stdweb-derive", - "stdweb-internal-macros", - "stdweb-internal-runtime", - "wasm-bindgen", -] - -[[package]] -name = "stdweb-derive" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" -dependencies = [ - "proc-macro2", - "quote", - "serde", - "serde_derive", - "syn", -] - -[[package]] -name = "stdweb-internal-macros" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" -dependencies = [ - "base-x", - "proc-macro2", - "quote", - "serde", - "serde_derive", - "serde_json", - "sha1", - "syn", -] - -[[package]] -name = "stdweb-internal-runtime" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" - -[[package]] -name = "syn" -version = "1.0.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "tempfile" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" -dependencies = [ - "cfg-if", - "libc", - "rand", - "redox_syscall", - "remove_dir_all", - "winapi", -] - -[[package]] -name = "thread_local" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd" -dependencies = [ - "once_cell", -] - -[[package]] -name = "time" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "time" -version = "0.2.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4752a97f8eebd6854ff91f1c1824cd6160626ac4bd44287f7f4ea2035a02a242" -dependencies = [ - "const_fn", - "libc", - "standback", - "stdweb", - "time-macros", - "version_check", - "winapi", -] - -[[package]] -name = "time-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957e9c6e26f12cb6d0dd7fc776bb67a706312e7299aed74c8dd5b17ebb27e2f1" -dependencies = [ - "proc-macro-hack", - "time-macros-impl", -] - -[[package]] -name = "time-macros-impl" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd3c141a1b43194f3f56a1411225df8646c55781d5f26db825b3d98507eb482f" -dependencies = [ - "proc-macro-hack", - "proc-macro2", - "quote", - "standback", - "syn", -] - -[[package]] -name = "tinyvec" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" - -[[package]] -name = "tokio" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e992e41e0d2fb9f755b37446f20900f64446ef54874f40a60c78f021ac6144" -dependencies = [ - "autocfg", - "bytes", - "libc", - "memchr", - "mio", - "num_cpus", - "once_cell", - "pin-project-lite", - "signal-hook-registry", - "tokio-macros", - "winapi", -] - -[[package]] -name = "tokio-macros" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9efc1aba077437943f7515666aa2b882dfabfbfdf89c819ea75a8d6e9eaba5e" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tokio-native-tls" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" -dependencies = [ - "native-tls", - "tokio", -] - -[[package]] -name = "tokio-stream" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50145484efff8818b5ccd256697f36863f587da82cf8b409c53adf1e840798e3" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "log", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "toml" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" -dependencies = [ - "serde", -] - -[[package]] -name = "tower-service" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" - -[[package]] -name = "tracing" -version = "0.1.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105" -dependencies = [ - "cfg-if", - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f480b8f81512e825f337ad51e94c1eb5d3bbdf2b363dcd01e2b19a9ffe3f8e" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tracing-core" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4ed65637b8390770814083d20756f87bfa2c21bf2f110babdc5438351746e4" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "tracing-log" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3" -dependencies = [ - "lazy_static", - "log", - "tracing-core", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "245da694cc7fc4729f3f418b304cb57789f1bed2a78c575407ab8a23f53cb4d3" -dependencies = [ - "ansi_term", - "lazy_static", - "matchers", - "regex", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log", -] - -[[package]] -name = "try-lock" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" - -[[package]] -name = "twoway" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c57ffb460d7c24cd6eda43694110189030a3d1dfe418416d9468fd1c1d290b47" -dependencies = [ - "memchr", - "unchecked-index", -] - -[[package]] -name = "ubyte" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42756bb9e708855de2f8a98195643dff31a97f0485d90d8467b39dc24be9e8fe" -dependencies = [ - "serde", -] - -[[package]] -name = "uncased" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baeed7327e25054889b9bd4f975f32e5f4c5d434042d59ab6cd4142c0a76ed0" -dependencies = [ - "serde", - "version_check", -] - -[[package]] -name = "unchecked-index" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeba86d422ce181a719445e51872fa30f1f7413b62becb52e95ec91aa262d85c" - -[[package]] -name = "unicase" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" -dependencies = [ - "version_check", -] - -[[package]] -name = "unicase_serde" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ef53697679d874d69f3160af80bc28de12730a985d57bdf2b47456ccb8b11f1" -dependencies = [ - "serde", - "unicase", -] - -[[package]] -name = "unicode-bidi" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" - -[[package]] -name = "unicode-normalization" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unicode-segmentation" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" - -[[package]] -name = "unicode-xid" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" - -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - -[[package]] -name = "url" -version = "2.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" -dependencies = [ - "form_urlencoded", - "idna", - "matches", - "percent-encoding", -] - -[[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.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" - -[[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.2+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - -[[package]] -name = "wasm-bindgen" -version = "0.2.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b" -dependencies = [ - "bumpalo", - "lazy_static", - "log", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8d7523cb1f2a4c96c1317ca690031b714a51cc14e05f712446691f413f5d39" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc" - -[[package]] -name = "web-sys" -version = "0.3.55" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "winreg" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69" -dependencies = [ - "winapi", -] - -[[package]] -name = "yansi" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc79f4a1e39857fc00c3f662cbf2651c771f00e9c15fe2abc341806bd46bd71" diff --git a/backend/server/src/admin.rs b/backend/server/src/admin.rs deleted file mode 100644 index ce942ba58..000000000 --- a/backend/server/src/admin.rs +++ /dev/null @@ -1,41 +0,0 @@ -use crate::database::{ - models::{AdminInfoResponse, OrganisationInfo, OrganisationUser, SuperUser, User}, - Database, -}; -use crate::error::JsonErr; -use rocket::{get, http::Status, post, serde::json::Json}; - -#[get("/")] -pub async fn get(user: User, db: Database) -> Json { - Json(AdminInfoResponse { - organisations: db - .run(move |conn| { - user.get_all_org_ids_belonging(conn) - .into_iter() - .filter(|org_id| { - OrganisationUser::organisation_admin_level(*org_id, user.id, conn) - .is_at_least_director() - .check() - .is_ok() - }) - .map(|org| OrganisationInfo::new(org, conn)) - .collect::>() - }) - .await, - }) -} - -#[post("/make_superuser", data = "")] -pub async fn make_superuser( - _user: SuperUser, - db: Database, - email: Json, -) -> Result<(), JsonErr<()>> { - db.run(move |conn| { - User::get_from_email(conn, &email.into_inner()) - .map(|user| user.make_superuser(conn).ok()) - .flatten() - }) - .await - .ok_or(JsonErr((), Status::BadRequest)) -} diff --git a/backend/server/src/application.rs b/backend/server/src/application.rs deleted file mode 100644 index 907984963..000000000 --- a/backend/server/src/application.rs +++ /dev/null @@ -1,292 +0,0 @@ -use diesel::prelude::*; - -use crate::database::{ - models::{ - Answer, Application, Campaign, Comment, NewAnswer, NewApplication, NewRating, - OrganisationUser, Question, Rating, Role, User, - }, - schema::ApplicationStatus, - Database, -}; -use crate::error::JsonErr; -use rocket::{ - get, - http::Status, - post, put, - serde::{json::Json, Deserialize, Serialize}, - FromForm, -}; - -#[derive(Serialize)] -pub enum ApplicationError { - Unauthorized, - UserNotFound, - RoleNotFound, - UnableToCreate, - UnableToUpdate, - AppNotFound, - QuestionNotFound, - InvalidInput, - CampaignEnded, -} - -#[derive(Deserialize)] -pub struct ApplicationReq { - pub role_id: i32, -} - -#[post("/", data = "")] -pub async fn create_application( - app_req: Json, - user: User, - db: Database, -) -> Result, JsonErr> { - use crate::database::schema::applications::dsl::*; - use diesel::prelude::*; - use diesel::query_dsl::RunQueryDsl; - - let new_application = NewApplication { - user_id: user.id, - role_id: app_req.role_id, - status: ApplicationStatus::Pending, - private_status: ApplicationStatus::Pending, - }; - - let application = db - .run(move |conn| { - let role = Role::get_from_id(conn, app_req.role_id)?; - let camp = Campaign::get_from_id(conn, role.campaign_id)?; - - if !camp.is_running() { - return None; - } - - let count = applications - .filter(role_id.eq(app_req.role_id).and(user_id.eq(user.id))) - .select(id) - .load::(conn) - .unwrap_or_else(|_| vec![]) - .len(); - - if count > 0 { - return None; - } - - NewApplication::insert(&new_application, conn) - }) - .await - .ok_or(JsonErr( - ApplicationError::UnableToCreate, - Status::BadRequest, - ))?; - - Ok(Json(application)) -} - -#[derive(FromForm, Deserialize)] -pub struct RatingInput { - rating: i32, -} - -#[put("//rating", data = "")] -pub async fn create_rating( - application_id: i32, - rating: Json, - user: User, - db: Database, -) -> Result, JsonErr> { - db.run(move |conn| { - OrganisationUser::application_admin_level(application_id, user.id, &conn) - .is_at_least_director() - .check() - .map_err(|_| JsonErr(ApplicationError::Unauthorized, Status::Forbidden))?; - - NewRating::insert( - &NewRating { - application_id, - rater_user_id: user.id, - rating: rating.rating, - }, - &conn, - ) - .ok_or(JsonErr( - ApplicationError::UnableToCreate, - Status::InternalServerError, - ))?; - - Ok(Json(())) - }) - .await -} - -#[post("/answer", data = "")] -pub async fn submit_answer( - user: User, - db: Database, - answer: Json, -) -> Result, JsonErr> { - db.run(move |conn| { - let application = Application::get(answer.application_id, &conn) - .ok_or(JsonErr(ApplicationError::AppNotFound, Status::NotFound))?; - if application.user_id != user.id { - return Err(JsonErr(ApplicationError::Unauthorized, Status::Forbidden)); - } - - let question = Question::get_from_id(&conn, answer.question_id).ok_or(JsonErr( - ApplicationError::QuestionNotFound, - Status::BadRequest, - ))?; - if answer.description.len() as i32 > question.max_bytes { - return Err(JsonErr(ApplicationError::InvalidInput, Status::BadRequest)); - } - - NewAnswer::insert(&answer, &conn).ok_or(JsonErr( - ApplicationError::UnableToCreate, - Status::InternalServerError, - ))?; - - Ok(Json(())) - }) - .await -} - -#[derive(Serialize)] -pub struct AnswersResponse { - answers: Vec, -} - -#[get("//answers")] -pub async fn get_answers( - application_id: i32, - user: User, - db: Database, -) -> Result, JsonErr> { - db.run(move |conn| { - let app = Application::get(application_id, &conn) - .ok_or(JsonErr(ApplicationError::AppNotFound, Status::NotFound))?; - - OrganisationUser::role_admin_level(app.role_id, user.id, &conn) - .is_at_least_director() - .check() - .map_err(|_| JsonErr(ApplicationError::Unauthorized, Status::Forbidden))?; - - Ok(Json(AnswersResponse { - answers: Answer::get_all_from_application_id(conn, application_id), - })) - }) - .await -} - -#[derive(Serialize)] -pub struct RatingsResponse { - ratings: Vec, -} - -#[get("//ratings")] -pub async fn get_ratings( - application_id: i32, - user: User, - db: Database, -) -> Result, JsonErr> { - db.run(move |conn| { - let app = Application::get(application_id, &conn) - .ok_or(JsonErr(ApplicationError::AppNotFound, Status::NotFound))?; - - OrganisationUser::role_admin_level(app.role_id, user.id, &conn) - .is_at_least_director() - .check() - .map_err(|_| JsonErr(ApplicationError::Unauthorized, Status::Forbidden))?; - - Ok(Json(RatingsResponse { - ratings: Rating::get_all_from_application_id(conn, application_id), - })) - }) - .await -} - -#[put("//status", data = "")] -pub async fn set_status( - application_id: i32, - new_status: Json, - user: User, - db: Database, -) -> Result, JsonErr> { - use crate::database::schema::applications::dsl::*; - - db.run(move |conn| { - OrganisationUser::application_admin_level(application_id, user.id, &conn) - .is_at_least_director() - .check() - .map_err(|_| JsonErr(ApplicationError::Unauthorized, Status::Forbidden))?; - - diesel::update(applications.filter(id.eq(application_id))) - .set(status.eq(new_status.into_inner())) - .execute(conn) - .map_err(|_| { - JsonErr( - ApplicationError::UnableToUpdate, - Status::InternalServerError, - ) - })?; - - Ok(Json(())) - }) - .await -} - -#[put("//private_status", data = "")] -pub async fn set_private_status( - application_id: i32, - new_status: Json, - user: User, - db: Database, -) -> Result, JsonErr> { - use crate::database::schema::applications::dsl::*; - - db.run(move |conn| { - OrganisationUser::application_admin_level(application_id, user.id, &conn) - .is_at_least_director() - .check() - .map_err(|_| JsonErr(ApplicationError::Unauthorized, Status::Forbidden))?; - - diesel::update(applications.filter(id.eq(application_id))) - .set(private_status.eq(new_status.into_inner())) - .execute(conn) - .map_err(|_| { - JsonErr( - ApplicationError::UnableToUpdate, - Status::InternalServerError, - ) - })?; - - Ok(Json(())) - }) - .await -} - -#[derive(Serialize)] -pub struct CommentsResponse { - comments: Vec, -} - -#[get("//comments")] -pub async fn get_comments( - application_id: i32, - user: User, - db: Database, -) -> Result, JsonErr> { - db.run(move |conn| { - let app = Application::get(application_id, &conn) - .ok_or(JsonErr(ApplicationError::AppNotFound, Status::NotFound))?; - - OrganisationUser::role_admin_level(app.role_id, user.id, &conn) - .is_at_least_director() - .check() - .map_err(|_| JsonErr(ApplicationError::Unauthorized, Status::Forbidden))?; - - Ok(Json(CommentsResponse { - comments: Comment::get_all_from_application_id(conn, application_id), - })) - }) - .await -} diff --git a/backend/server/src/auth.rs b/backend/server/src/auth.rs deleted file mode 100644 index 4f7e805ea..000000000 --- a/backend/server/src/auth.rs +++ /dev/null @@ -1,376 +0,0 @@ -use crate::error::JsonErr; -use crate::{ - database::{ - models::{NewUser, User}, - schema::UserGender, - Database, - }, - state::ApiState, -}; -use dotenv; -use jsonwebtoken::{Algorithm, Header, Validation}; -use reqwest::header; -use rocket::{ - http::Status, - post, - request::FromRequest, - request::{self, Outcome}, - serde::json::Json, - Request, State, -}; -use serde::{Deserialize, Serialize}; -use serde_json::Value; - -const GOOGLE_TOKEN_URL: &str = "https://oauth2.googleapis.com/token"; -const OPENID_EMAIL_FIELD: &str = "email"; -const OPENID_NAME_FIELD: &str = "name"; - -#[derive(Debug, Serialize, Deserialize)] -pub struct AuthJwt { - pub user_id: u32, -} - -pub struct Auth { - pub jwt: AuthJwt, -} - -#[derive(Debug)] -pub enum AuthError { - MissingAuthorizationHeader, - MissingBearer, - InvalidJwt, - ApiStateMissing, - NotSuperUser, -} - -#[rocket::async_trait] -impl<'r> FromRequest<'r> for Auth { - type Error = AuthError; - - async fn from_request(request: &'r Request<'_>) -> request::Outcome { - let api_state = match request.guard::<&State>().await { - Outcome::Success(api_state) => api_state, - _ => { - return Outcome::Failure((Status::InternalServerError, AuthError::ApiStateMissing)) - } - }; - - let header = match request.headers().get_one("Authorization") { - Some(header) => header, - None => { - return Outcome::Failure(( - Status::BadRequest, - AuthError::MissingAuthorizationHeader, - )) - } - }; - - if !header.starts_with("Bearer ") { - return Outcome::Failure((Status::BadRequest, AuthError::MissingBearer)); - } - - let token = header.trim_start_matches("Bearer "); - - let mut validation = Validation::new(Algorithm::HS256); - validation.validate_exp = false; - validation.required_spec_claims.clear(); - - let token = match jsonwebtoken::decode::( - token, - &api_state.jwt_decoding_key, - &validation, - ) { - Ok(data) => data.claims, - Err(_) => return Outcome::Failure((Status::BadRequest, AuthError::InvalidJwt)), - }; - - return Outcome::Success(Auth { jwt: token }); - } -} - -async fn get_access_token(oauth_code: &str, state: &State) -> Option { - #[derive(Serialize)] - struct TokenForm<'a> { - code: &'a str, - client_id: String, - client_secret: String, - redirect_uri: String, - grant_type: &'static str, - } - - #[derive(Deserialize)] - #[allow(unused)] - struct TokenResponse { - access_token: String, - expires_in: u32, - scope: String, - token_type: String, - id_token: String, - } - - let token_json = state - .reqwest_client - .post(GOOGLE_TOKEN_URL) - .form(&TokenForm { - code: oauth_code, - client_id: dotenv::var("GOOGLE_CLIENT_ID").expect("GOOGLE_CLIENT_ID should be in env"), - client_secret: dotenv::var("GOOGLE_CLIENT_SECRET") - .expect("GOOGLE_CLIENT_SECRET should be in env"), - redirect_uri: dotenv::var("GOOGLE_REDIRECT_URI") - .expect("GOOGLE_CLIENT_SECRET should be in env"), - grant_type: "authorization_code", - }) - .send() - .await - .map_err(|e| eprintln!("Oauth request failed: {}", e)) - .ok()? - .json::() - .await - .ok()?; - - match serde_json::from_value::(token_json.clone()) { - Ok(t) => Some(t.access_token), - Err(e) => { - eprintln!( - "Failed to parse token response: {}\nJSON is {}", - e, token_json - ); - None - } - } -} - -struct UserDetails { - email: Option, - name: Option, -} - -async fn get_user_details(state: &State, token: &str) -> UserDetails { - let response = match state - .reqwest_client - .get(&state.userinfo_endpoint) - .header(header::AUTHORIZATION, format!("Bearer {}", token)) - .send() - .await - { - Ok(response) => response, - Err(_) => { - return UserDetails { - email: None, - name: None, - } - } - }; - - let mut user_info = match response.json::().await { - Ok(user_info) => user_info, - Err(_) => { - return UserDetails { - email: None, - name: None, - } - } - }; - - let email = match user_info.get_mut(OPENID_EMAIL_FIELD) { - Some(Value::String(email)) => Some(email.to_string()), - _ => None, - }; - - let name = match user_info.get_mut(OPENID_NAME_FIELD) { - Some(Value::String(name)) => Some(name.to_string()), - _ => None, - }; - - UserDetails { email, name } -} - -#[derive(Deserialize)] -pub struct SignInBody { - oauth_token: String, -} - -#[derive(Serialize)] -pub struct SignInResponse { - token: String, - name: String, -} - -#[derive(Serialize)] -pub enum SignInError { - InvalidOAuthCode, - GoogleOAuthInternalError, - SignupRequired { - signup_token: String, - name: Option, - }, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct SignupJwt { - pub auth_token: String, -} - -#[post("/signin", data = "")] -pub async fn signin( - body: Json, - state: &State, - db: Database, -) -> Result, JsonErr> { - let token = get_access_token(&body.oauth_token, state) - .await - .ok_or_else(|| { - eprintln!( - "Failed to get access token for oauth token {}", - body.oauth_token - ); - JsonErr(SignInError::InvalidOAuthCode, Status::Forbidden) - })?; - - let details = get_user_details(state, &token).await; - - let email = details.email.ok_or(JsonErr( - SignInError::GoogleOAuthInternalError, - Status::Forbidden, - ))?; - - let user = db - .run(move |conn| User::get_from_email(conn, &email)) - .await - .ok_or_else(|| { - let jwt = SignupJwt { auth_token: token }; - - let token = jsonwebtoken::encode( - &Header::new(jsonwebtoken::Algorithm::HS256), - &jwt, - &state.jwt_encoding_key, - ) - .expect("creating jwt should never fail"); - - JsonErr( - SignInError::SignupRequired { - signup_token: token, - name: details.name, - }, - Status::Ok, - ) - })?; - - let auth = AuthJwt { - user_id: user.id as u32, - }; - - let token = jsonwebtoken::encode( - &Header::new(jsonwebtoken::Algorithm::HS256), - &auth, - &state.jwt_encoding_key, - ) - .expect("creating jwt should never fail"); - - Ok(Json(SignInResponse { - token, - name: user.display_name, - })) -} - -#[derive(Deserialize, Clone)] -pub struct SignUpBody { - signup_token: String, - zid: String, - display_name: String, - degree_name: String, - degree_starting_year: u32, - gender: UserGender, - pronouns: String, -} - -#[derive(Serialize)] -pub struct SignUpResponse { - token: String, -} - -#[derive(Serialize)] -pub enum SignUpError { - InvalidSignupToken, - GoogleOAuthInternalError, - AccountAlreadyExists, -} - -#[post("/signup", data = "")] -pub async fn signup( - body: Json, - state: &State, - db: Database, -) -> Result, JsonErr> { - let mut validation = Validation::new(Algorithm::HS256); - validation.validate_exp = false; - validation.required_spec_claims.clear(); - - let token = match jsonwebtoken::decode::( - &body.signup_token, - &state.jwt_decoding_key, - &validation, - ) { - Ok(data) => data.claims.auth_token, - Err(_) => { - return Err(JsonErr( - SignUpError::InvalidSignupToken, - Status::FailedDependency, - )) - } - }; - - let details = get_user_details(state, &token).await; - - let email = details.email.ok_or(JsonErr( - SignUpError::GoogleOAuthInternalError, - Status::FailedDependency, - ))?; - - { - let email = email.clone(); - - if db - .run(move |conn| User::get_from_email(conn, &email)) - .await - .is_some() - { - return Err(JsonErr(SignUpError::AccountAlreadyExists, Status::ImUsed)); - } - } - - let user = { - let email = email.clone(); - let body = body.clone(); - - db.run(move |conn| { - let user = NewUser { - email, - zid: body.zid.to_string(), - display_name: body.display_name.to_string(), - degree_name: body.degree_name.to_string(), - degree_starting_year: body.degree_starting_year as i32, - gender: body.gender, - pronouns: body.pronouns.to_string(), - superuser: User::get_number(conn) == 0, - }; - - user.insert(conn) - .expect("we already ensured a conflicting user does not exist") - }) - .await - }; - - let auth = AuthJwt { - user_id: user.id as u32, - }; - - let token = jsonwebtoken::encode( - &Header::new(jsonwebtoken::Algorithm::HS256), - &auth, - &state.jwt_encoding_key, - ) - .expect("creating jwt should never fail"); - - Ok(Json(SignUpResponse { token })) -} diff --git a/backend/server/src/bin.rs b/backend/server/src/bin.rs deleted file mode 100644 index f15465577..000000000 --- a/backend/server/src/bin.rs +++ /dev/null @@ -1,170 +0,0 @@ -extern crate diesel; - -#[macro_use] -extern crate diesel_migrations; - -use backend::cors::cors; -use backend::database::Database; -use backend::{auth::Auth, images::IMAGE_BASE_PATH}; -use diesel::pg::PgConnection; -use diesel::prelude::*; -use diesel_migrations::*; -use figment::{providers::Serialized, Figment}; -use rocket::{routes, serde::json::Value}; -use std::{env, fs, path::Path}; - -#[rocket::get("/foo")] -fn authed_call(auth: Auth) -> String { - format!("hello, your user id is {}", auth.jwt.user_id) -} - -embed_migrations!(); - -#[rocket::main] -async fn main() { - dotenv::dotenv().ok(); - - let db_url = run_migrations(); - - let api_state = backend::state::api_state().await; - - let cors = cors(); - - let config_map: Value = serde_json::from_str(&format!( - r#"{{ - "databases": {{ - "database": {{ - "url": "{}" - }} - }}, - "log_level": "debug", - "address": "0.0.0.0", - "limits": {{ - "json": "10485760" - }} - }}"#, - db_url - )) - .unwrap(); - - let figment = Figment::from(rocket::Config::default()).merge(Serialized::globals(config_map)); - - // create images dir if not found - fs::create_dir_all(Path::new(IMAGE_BASE_PATH)).ok(); - - let _ = rocket::custom(figment) - .manage(api_state) - .attach(Database::fairing()) - .attach(cors) - .mount("/", routes![authed_call]) - .mount( - "/organisation", - routes![ - backend::organisation::new, - backend::organisation::get_from_id, - backend::organisation::delete, - backend::organisation::get_admins, - backend::organisation::set_admins, - backend::organisation::is_admin, - backend::organisation::get_from_ids, - backend::organisation::invite_uid, - backend::organisation::invite_email, - backend::organisation::set_logo, - ], - ) - .mount( - "/auth", - routes![backend::auth::signin, backend::auth::signup], - ) - .mount( - "/campaign", - routes![ - backend::campaigns::get, - backend::campaigns::update, - backend::campaigns::roles, - backend::campaigns::new, - backend::campaigns::delete_campaign, - backend::campaigns::get_all_campaigns, - backend::campaigns::set_cover_image, - ], - ) - .mount( - "/user", - routes![ - backend::user::get_user, - backend::user::get_user_campaigns, - backend::user::get, - ], - ) - .mount( - "/application", - routes![ - backend::application::create_application, - backend::application::create_rating, - backend::application::submit_answer, - backend::application::get_answers, - backend::application::get_ratings, - backend::application::set_status, - backend::application::set_private_status, - backend::application::get_comments, - ], - ) - .mount( - "/role", - routes![ - backend::role::get_role, - backend::role::update_role, - backend::role::new_role, - backend::role::get_questions, - backend::role::get_applications, - ], - ) - .mount( - "/comment", - routes![ - backend::comment::create_comment, - backend::comment::get_comment_from_id - ], - ) - .mount( - "/question", - routes![ - backend::question::get_question, - backend::question::edit_question, - backend::question::delete_question - ], - ) - .mount( - "/admin", - routes![backend::admin::get, backend::admin::make_superuser], - ) - .mount("/static", routes![backend::static_resources::files]) - .launch() - .await - .unwrap(); -} - -fn run_migrations() -> String { - let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set"); - - assert!(&database_url[database_url.len() - 5..] == "chaos"); - - let database_url_no_chaos = String::from(&database_url[..database_url.len() - 5]); - - let main_connection = PgConnection::establish(&database_url_no_chaos) - .expect(&format!("Error connecting to {}", database_url_no_chaos)); - - match diesel::sql_query("CREATE DATABASE chaos").execute(&main_connection) { - _ => (), - }; - - let chaos_connection = PgConnection::establish(&database_url) - .expect(&format!("Error connecting to {}", database_url)); - - embedded_migrations::run_with_output(&chaos_connection, &mut std::io::stdout()) - .expect("Failed to run migrations"); - - println!("Finishing running migrations"); - - return database_url; -} diff --git a/backend/server/src/campaigns.rs b/backend/server/src/campaigns.rs deleted file mode 100644 index ca64a8eb1..000000000 --- a/backend/server/src/campaigns.rs +++ /dev/null @@ -1,308 +0,0 @@ -use crate::error::JsonErr; -use crate::images::get_image_path; -use crate::{ - database::{ - models::{ - Campaign, CampaignWithRoles, NewCampaignInput, NewQuestion, OrganisationUser, Role, - RoleUpdate, UpdateCampaignInput, User, - }, - Database, - }, - images::{get_http_image_path, save_image, try_decode_data, ImageLocation}, -}; -use rocket::{data::Data, delete, get, http::Status, post, put, serde::json::Json}; -use serde::{Deserialize, Serialize}; -use std::fs::remove_file; - -use uuid::Uuid; - -#[derive(Serialize)] -pub enum CampaignError { - CampaignNotFound, - Unauthorized, - UnableToCreate, - InvalidInput, -} - -#[get("/")] -pub async fn get(campaign_id: i32, db: Database) -> Result, JsonErr> { - let mut campaign = db - .run(move |conn| Campaign::get_from_id(conn, campaign_id)) - .await; - - campaign = campaign.map(|mut campaign| { - campaign.cover_image = campaign - .cover_image - .map(|logo_uuid| get_http_image_path(ImageLocation::ORGANISATIONS, &logo_uuid)); - campaign - }); - - match campaign { - Some(campaign) => { - if campaign.published { - Ok(Json(campaign)) - } else { - Err(JsonErr(CampaignError::Unauthorized, Status::Forbidden)) - } - } - None => Err(JsonErr(CampaignError::CampaignNotFound, Status::NotFound)), - } -} - -#[derive(Serialize)] -pub struct DashboardCampaignGroupings { - pub current_campaigns: Vec, - pub past_campaigns: Vec, -} - -#[get("/all")] -pub async fn get_all_campaigns(user: User, db: Database) -> Json { - fn with_http_cover_images(campaigns: Vec) -> Vec { - campaigns - .into_iter() - .map(CampaignWithRoles::with_http_cover_image) - .collect() - } - - let (current_campaigns, past_campaigns) = db - .run(move |conn| { - ( - with_http_cover_images(Campaign::get_all_public_with_roles(conn, user.id)), - with_http_cover_images(Campaign::get_all_public_ended_with_roles(conn, user.id)), - ) - }) - .await; - - Json(DashboardCampaignGroupings { - current_campaigns, - past_campaigns, - }) -} - -#[put("/", data = "")] -pub async fn update( - campaign_id: i32, - update_campaign: Json, - user: User, - db: Database, -) -> Result, JsonErr> { - db.run(move |conn| { - OrganisationUser::campaign_admin_level(campaign_id, user.id, &conn) - .is_at_least_director() - .check() - .or_else(|_| Err(JsonErr(CampaignError::Unauthorized, Status::Forbidden)))?; - - Campaign::update(conn, campaign_id, &update_campaign); - - Ok(Json(())) - }) - .await -} - -#[derive(Serialize, Deserialize)] -pub struct RoleInput { - pub name: String, - pub description: Option, - pub min_available: i32, - pub max_available: i32, - pub questions_for_role: Vec, -} - -fn default_max_bytes() -> i32 { - 100 -} - -#[derive(Serialize, Deserialize)] -pub struct QuestionInput { - pub title: String, - pub description: Option, - #[serde(default = "default_max_bytes")] - pub max_bytes: i32, - #[serde(default)] - pub required: bool, -} - -#[derive(Deserialize)] -pub struct NewCampaignWithData { - pub campaign: NewCampaignInput, - pub roles: Vec, - pub questions: Vec, -} - -#[post("/", data = "")] -pub async fn new( - new_campaign: Json, - user: User, - db: Database, -) -> Result, JsonErr> { - let inner = new_campaign.into_inner(); - let NewCampaignWithData { - campaign, - roles, - questions, - } = inner; - - let mut new_questions: Vec = questions - .into_iter() - .map(|x| NewQuestion { - role_ids: vec![], - title: x.title, - description: x.description, - max_bytes: x.max_bytes, - required: x.required, - }) - .collect(); - - db.run(move |conn| { - OrganisationUser::organisation_admin_level(campaign.organisation_id, user.id, &conn) - .is_at_least_director() - .check() - .or_else(|_| Err(JsonErr(CampaignError::Unauthorized, Status::Forbidden)))?; - - let campaign = Campaign::create(conn, &campaign).ok_or_else(|| { - eprintln!("Failed to create campaign for some reason: {:?}", campaign); - JsonErr(CampaignError::UnableToCreate, Status::InternalServerError) - })?; - - for role in roles { - let new_role = RoleUpdate { - campaign_id: campaign.id, - name: role.name, - description: role.description, - min_available: role.min_available, - max_available: role.max_available, - finalised: campaign.published, - }; - let inserted_role = new_role.insert(conn).ok_or_else(|| { - eprintln!("Failed to create role for some reason: {:?}", new_role); - JsonErr(CampaignError::UnableToCreate, Status::InternalServerError) - })?; - - for question in role.questions_for_role { - if question < new_questions.len() { - new_questions[question].role_ids.push(inserted_role.id); - } - } - } - - for question in new_questions { - if question.role_ids.len() == 0 { - return Err(JsonErr(CampaignError::InvalidInput, Status::BadRequest)); - } - question.insert(conn).ok_or_else(|| { - eprintln!("Failed to create question for some reason"); - JsonErr(CampaignError::UnableToCreate, Status::InternalServerError) - })?; - } - - Ok(Json(campaign)) - }) - .await -} - -#[delete("/")] -pub async fn delete_campaign( - campaign_id: i32, - user: User, - db: Database, -) -> Result, JsonErr> { - db.run(move |conn| { - // need to be admin to create new campaign - OrganisationUser::campaign_admin_level(campaign_id, user.id, &conn) - .is_admin() - .check() - .or_else(|_| Err(JsonErr(CampaignError::Unauthorized, Status::Forbidden)))?; - - Campaign::delete_deep(conn, campaign_id); - - Ok(Json(())) - }) - .await -} - -#[derive(Serialize)] -pub struct RolesResponse { - roles: Vec, -} - -#[derive(Serialize)] -pub enum RolesError { - CampaignNotFound, - Unauthorized, - RoleAlreadyExists, -} - -#[get("//roles")] -pub async fn roles( - campaign_id: i32, // campaign_id has namespace conflict - user: User, - db: Database, -) -> Result, JsonErr> { - db.run(move |conn| { - let campaign = Campaign::get_from_id(conn, campaign_id) - .ok_or_else(|| JsonErr(RolesError::CampaignNotFound, Status::NotFound))?; - - OrganisationUser::campaign_admin_level(campaign_id, user.id, &conn) - .is_at_least_director() - .or(campaign.published) // only if not (read only and campaign is unpublished) - .check() - .or_else(|_| Err(JsonErr(RolesError::Unauthorized, Status::Forbidden)))?; - - let roles = Role::get_all_from_campaign_id(conn, campaign.id); - - Ok(Json(RolesResponse { roles })) - }) - .await -} - -#[derive(Serialize)] -pub enum LogoError { - Unauthorized, - ImageDeletionFailure, - ImageStoreFailure, -} - -#[put("//cover_image", data = "")] -pub async fn set_cover_image( - campaign_id: i32, - user: User, - db: Database, - image: Data<'_>, -) -> Result, JsonErr> { - db.run(move |conn| { - OrganisationUser::campaign_admin_level(campaign_id, user.id, &conn) - .is_at_least_director() - .check() - .or_else(|_| Err(JsonErr(LogoError::Unauthorized, Status::Forbidden))) - }) - .await?; - - let old_logo_uuid = db - .run(move |conn| Campaign::get_cover_image(&conn, campaign_id)) - .await; - let logo_uuid = Uuid::new_v4().as_hyphenated().to_string() + ".webp"; - - let image = try_decode_data(image).await.or_else(|_| { - Err(JsonErr( - LogoError::ImageDeletionFailure, - Status::InternalServerError, - )) - })?; - - save_image(image, ImageLocation::CAMPAIGNS, &logo_uuid) - .map_err(|_| JsonErr(LogoError::ImageStoreFailure, Status::InternalServerError))?; - - let logo_uuid_clone = logo_uuid.clone(); - - db.run(move |conn| Campaign::set_cover_image(&conn, campaign_id, &logo_uuid_clone)) - .await; - - if let Some(uuid) = old_logo_uuid { - remove_file(get_image_path(ImageLocation::CAMPAIGNS, &uuid)).ok(); - } - - Ok(Json(get_http_image_path( - ImageLocation::CAMPAIGNS, - &logo_uuid, - ))) -} diff --git a/backend/server/src/comment.rs b/backend/server/src/comment.rs deleted file mode 100644 index bd123cd41..000000000 --- a/backend/server/src/comment.rs +++ /dev/null @@ -1,75 +0,0 @@ -use crate::database::{ - models::{Comment, NewComment, OrganisationUser, User}, - Database, -}; -use crate::error::JsonErr; -use rocket::{ - get, - http::Status, - put, - serde::{json::Json, Deserialize, Serialize}, -}; - -#[derive(Deserialize)] -pub struct NewCommentInput { - pub application_id: i32, - pub description: String, -} - -#[derive(Serialize)] -pub enum CommentError { - Unauthorized, - CouldNotInsert, - CommentNotFound, -} - -#[put("/", data = "")] -pub async fn create_comment( - new_comment_input: Json, - user: User, - db: Database, -) -> Result, JsonErr> { - // need to be director to comment - let app_id = new_comment_input.application_id; // stack copy of i32 - db.run(move |conn| { - OrganisationUser::application_admin_level(app_id, user.id, &conn) - .is_at_least_director() - .check() - }) - .await - .or_else(|_| Err(JsonErr(CommentError::Unauthorized, Status::Forbidden)))?; - - let new_comment = NewComment { - application_id: new_comment_input.application_id, - commenter_user_id: user.id, - description: new_comment_input.description.to_string(), - }; - let comment = db - .run(move |conn| NewComment::insert(&new_comment, conn)) - .await - .ok_or_else(|| JsonErr(CommentError::CouldNotInsert, Status::InternalServerError))?; - - Ok(Json(comment)) -} - -#[get("/")] -pub async fn get_comment_from_id( - comment_id: i32, - user: User, - db: Database, -) -> Result, JsonErr> { - db.run(move |conn| { - OrganisationUser::comment_admin_level(comment_id, user.id, &conn) - .is_at_least_director() - .check() - }) - .await - .or_else(|_| Err(JsonErr(CommentError::Unauthorized, Status::Forbidden)))?; - - let comment = db - .run(move |conn| Comment::get_from_id(conn, comment_id)) - .await - .ok_or_else(|| JsonErr(CommentError::CommentNotFound, Status::NotFound))?; - - Ok(Json(comment)) -} diff --git a/backend/server/src/cors.rs b/backend/server/src/cors.rs deleted file mode 100644 index 12db39f5d..000000000 --- a/backend/server/src/cors.rs +++ /dev/null @@ -1,21 +0,0 @@ -use rocket_cors::{AllowedHeaders, AllowedOrigins, Cors}; - -pub fn cors() -> Cors { - let cors = rocket_cors::CorsOptions { - allowed_origins: AllowedOrigins::All, - allowed_methods: { - // why do i have to do this, honestly - use rocket::http::Method::*; - vec![Get, Put, Post, Delete, Options, Head, Trace, Connect, Patch] - .into_iter() - .map(From::from) - .collect() - }, - allowed_headers: AllowedHeaders::All, - ..Default::default() - } - .to_cors() - .expect("Failed to create CORS options"); - - cors -} diff --git a/backend/server/src/database/mod.rs b/backend/server/src/database/mod.rs deleted file mode 100644 index 97015d397..000000000 --- a/backend/server/src/database/mod.rs +++ /dev/null @@ -1,7 +0,0 @@ -pub mod models; -pub mod schema; - -use rocket_sync_db_pools::database; - -#[database("database")] -pub struct Database(diesel::PgConnection); diff --git a/backend/server/src/database/models.rs b/backend/server/src/database/models.rs deleted file mode 100644 index d42360815..000000000 --- a/backend/server/src/database/models.rs +++ /dev/null @@ -1,1425 +0,0 @@ -use crate::images::{get_http_image_path, ImageLocation}; - -use super::schema::{ - answers, applications, campaigns, comments, organisation_users, organisations, questions, - ratings, roles, users, -}; -use super::schema::{AdminLevel, ApplicationStatus, UserGender}; -use chrono::NaiveDateTime; -use chrono::Utc; -use diesel::prelude::*; -use diesel::PgConnection; -use rocket::FromForm; -use serde::{Deserialize, Serialize}; -use std::collections::HashSet; -use std::fs::remove_file; -use std::path::Path; - -#[derive(Queryable)] -pub struct User { - pub id: i32, - pub email: String, - pub zid: String, - pub display_name: String, - pub degree_name: String, - pub degree_starting_year: i32, - pub gender: UserGender, - pub pronouns: String, - pub superuser: bool, - pub created_at: NaiveDateTime, - pub updated_at: NaiveDateTime, -} - -pub struct SuperUser { - user: User, -} - -impl SuperUser { - pub fn new(user: User) -> Self { - Self { user } - } - - pub fn user(&self) -> &User { - &self.user - } -} -#[derive(Insertable)] -#[table_name = "users"] -pub struct NewUser { - pub email: String, - pub zid: String, - pub display_name: String, - pub degree_name: String, - pub degree_starting_year: i32, - pub gender: UserGender, - pub pronouns: String, - pub superuser: bool, -} - -impl User { - pub fn get_all(conn: &PgConnection) -> Vec { - use crate::database::schema::users::dsl::*; - - users.order(id.asc()).load(conn).unwrap_or_else(|_| vec![]) - } - - pub fn make_superuser(&self, conn: &PgConnection) -> Result<(), diesel::result::Error> { - use crate::database::schema::users::dsl::*; - - diesel::update(users.filter(id.eq(self.id))) - .set(superuser.eq(true)) - .execute(conn)?; - - Ok(()) - } - - pub fn get_number(conn: &PgConnection) -> i64 { - use crate::database::schema::users::dsl::*; - use diesel::dsl::count; - - users - .select(count(display_name)) - .first(conn) - .unwrap_or_else(|_| 0) - } - - pub fn get_from_id(conn: &PgConnection, id_val: i32) -> Option { - use crate::database::schema::users::dsl::*; - - users.filter(id.eq(id_val)).first(conn).ok() - } - - pub fn get_from_email(conn: &PgConnection, user_email: &str) -> Option { - use crate::database::schema::users::dsl::*; - - users.filter(email.eq(user_email)).first(conn).ok() - } - - pub fn get_all_campaigns(&self, conn: &PgConnection) -> Vec { - use crate::database::schema::campaigns::dsl::*; - - campaigns - .filter(organisation_id.eq(self.id)) - .order(id.asc()) - .load(conn) - .unwrap_or_else(|_| vec![]) - } - - pub fn get_all_org_ids_belonging(&self, conn: &PgConnection) -> Vec { - if self.superuser { - return organisations::table - .select(organisations::id) - .load::(conn) - .unwrap_or_else(|_| vec![]); - } - - organisation_users::table - .filter(organisation_users::user_id.eq(self.id)) - .select(organisation_users::organisation_id) - .load::(conn) - .unwrap_or_else(|_| vec![]) - } - - pub fn get_all_orgs_belonging(&self, conn: &PgConnection) -> Vec { - if self.superuser { - return organisations::table - .load::(conn) - .unwrap_or_else(|_| vec![]); - } - - organisation_users::table - .filter(organisation_users::user_id.eq(self.id)) - .inner_join( - organisations::table.on(organisations::id.eq(organisation_users::organisation_id)), - ) - .select(( - organisations::id, - organisations::name, - organisations::logo, - organisations::created_at, - organisations::updated_at, - )) - .load::(conn) - .unwrap_or_else(|_| vec![]) - } -} - -impl NewUser { - pub fn insert(&self, conn: &PgConnection) -> Option { - use crate::database::schema::users::dsl::*; - - self.insert_into(users).get_result(conn).ok() - } -} - -#[derive(Queryable, Serialize, Deserialize)] -pub struct Organisation { - pub id: i32, - pub name: String, - pub logo: Option, - pub created_at: NaiveDateTime, - pub updated_at: NaiveDateTime, -} - -#[derive(Insertable, FromForm, Deserialize)] -#[table_name = "organisations"] -pub struct NewOrganisation { - pub name: String, - pub logo: Option, -} - -impl Organisation { - pub fn get_all(conn: &PgConnection) -> Vec { - use crate::database::schema::organisations::dsl::*; - - organisations - .order(id.asc()) - .load(conn) - .unwrap_or_else(|_| vec![]) - } - - pub fn get_from_id(conn: &PgConnection, organisation_id: i32) -> Option { - use crate::database::schema::organisations::dsl::*; - - organisations - .filter(id.eq(organisation_id)) - .first(conn) - .ok() - } - - pub fn delete(conn: &PgConnection, organisation_id: i32) -> Option { - use crate::database::schema::organisations::dsl::*; - - let num = diesel::delete(organisations.filter(id.eq(organisation_id))) - .execute(conn) - .ok()?; - - if num > 0 { - Some(num) - } else { - None - } - } - - pub fn delete_deep(conn: &PgConnection, org_id: i32) -> Option<()> { - use crate::database::schema::organisation_users::dsl::*; - if let Some(logo) = Organisation::get_logo(conn, org_id) { - remove_file(Path::new(&logo)).ok(); - } - - let campaigns = Campaign::get_all_from_org_id(conn, org_id); - - for campaign in campaigns { - Campaign::delete_deep(conn, campaign.id)?; - } - - diesel::delete(organisation_users.filter(organisation_id.eq(org_id))) - .execute(conn) - .ok(); - - let num = Organisation::delete(conn, org_id)?; - - if num < 1 { - return None; - } - - Some(()) - } - - pub fn find_by_name(conn: &PgConnection, organisation_name: &str) -> Option { - use crate::database::schema::organisations::dsl::*; - - organisations - .filter(name.eq(organisation_name)) - .first(conn) - .ok() - } - - pub fn get_admin_ids(conn: &PgConnection, org_id: i32) -> Option> { - organisation_users::table - .filter(organisation_users::organisation_id.eq(org_id)) - .load::(conn) - .map(|org_users| { - org_users - .into_iter() - .filter(|org_user| org_user.admin_level == AdminLevel::Admin) - .map(|org_user| org_user.user_id) - .collect() - }) - .ok() - } - - // FIXME - rather than looping through all admins, filter the users if theyre in admin_ids - // FIXME - this only works if they're already in the organisation, need to insert them into the - // organistaion first? - pub fn set_admins(conn: &PgConnection, org_id: i32, admin_ids: &[i32]) -> Option { - use crate::database::schema::organisation_users::dsl::*; - - diesel::update( - organisation_users - .filter(organisation_id.eq(org_id)) - .filter(user_id.eq_any(admin_ids)), - ) - .set(admin_level.eq(AdminLevel::Admin)) - .execute(conn) - .ok() - } - - pub fn get_logo(conn: &PgConnection, org_id: i32) -> Option { - use crate::database::schema::organisations::dsl::*; - - organisations - .filter(id.eq(org_id)) - .select(logo) - .first(conn) - .unwrap() - } - - pub fn set_logo(conn: &PgConnection, org_id: i32, new_logo: &str) -> String { - use crate::database::schema::organisations::dsl::*; - - diesel::update(organisations.find(org_id)) - .set(logo.eq(new_logo)) - .get_result::(conn) - .unwrap() - .logo - .unwrap() - } -} - -impl NewOrganisation { - pub fn insert(&self, conn: &PgConnection) -> Option { - use crate::database::schema::organisations::dsl::*; - - self.insert_into(organisations).get_result(conn).ok() - } -} - -#[derive(Queryable, Associations)] -#[belongs_to(Organisation)] -#[belongs_to(User)] -pub struct OrganisationUser { - pub id: i32, - pub user_id: i32, - pub organisation_id: i32, - pub admin_level: AdminLevel, - pub created_at: NaiveDateTime, - pub updated_at: NaiveDateTime, -} - -#[derive(Insertable)] -#[table_name = "organisation_users"] -pub struct NewOrganisationUser { - pub user_id: i32, - pub organisation_id: i32, - pub admin_level: AdminLevel, -} - -impl OrganisationUser { - pub fn get( - conn: &PgConnection, - organisation_id_val: i32, - user_id_val: i32, - ) -> Option { - use crate::database::schema::organisation_users::dsl::*; - - organisation_users - .filter(organisation_id.eq(organisation_id_val)) - .filter(user_id.eq(user_id_val)) - .first(conn) - .ok() - } - - pub fn update_admin_level( - &self, - conn: &PgConnection, - admin_level_val: AdminLevel, - ) -> Option<()> { - use crate::database::schema::organisation_users::dsl::*; - - diesel::update( - organisation_users - .filter(organisation_id.eq(self.organisation_id)) - .filter(user_id.eq(self.user_id)), - ) - .set(admin_level.eq(admin_level_val)) - .execute(conn) - .map(|_| ()) - .ok() - } - - pub fn get_all(conn: &PgConnection) -> Vec { - use crate::database::schema::organisation_users::dsl::*; - - organisation_users - .order(id.asc()) - .load(conn) - .unwrap_or_else(|_| vec![]) - } - - pub fn get_all_from_user_id(conn: &PgConnection, user_id_val: i32) -> Vec { - use crate::database::schema::organisation_users::dsl::*; - - organisation_users - .filter(user_id.eq(user_id_val)) - .order(id.asc()) - .load(conn) - .unwrap_or_else(|_| vec![]) - } - - pub fn get_all_from_organisation_id( - conn: &PgConnection, - organisation_id_val: i32, - ) -> Vec { - use crate::database::schema::organisation_users::dsl::*; - - organisation_users - .filter(organisation_id.eq(organisation_id_val)) - .order(id.asc()) - .load(conn) - .unwrap_or_else(|_| vec![]) - } -} - -impl NewOrganisationUser { - pub fn insert(&self, conn: &PgConnection) -> Option { - use crate::database::schema::organisation_users::dsl::*; - - self.insert_into(organisation_users).get_result(conn).ok() - } -} - -#[derive(Queryable, Serialize, Debug, Associations)] -#[belongs_to(Organisation)] -pub struct Campaign { - pub id: i32, - pub organisation_id: i32, - pub name: String, - pub cover_image: Option, - pub description: String, - pub starts_at: NaiveDateTime, - pub ends_at: NaiveDateTime, - pub published: bool, - pub created_at: NaiveDateTime, - pub updated_at: NaiveDateTime, -} - -#[derive(FromForm, Deserialize)] -pub struct UpdateCampaignInput { - pub name: String, - pub cover_image: Option, - pub description: String, - pub starts_at: String, - pub ends_at: String, - pub published: bool, -} - -#[derive(AsChangeset)] -#[table_name = "campaigns"] -pub struct UpdateCampaignChangeset { - pub name: String, - pub cover_image: Option, - pub description: String, - pub starts_at: NaiveDateTime, - pub ends_at: NaiveDateTime, - pub published: bool, -} - -#[derive(Insertable, Debug)] -#[table_name = "campaigns"] -pub struct NewCampaign { - pub organisation_id: i32, - pub name: String, - pub cover_image: Option, - pub description: String, - pub starts_at: NaiveDateTime, - pub ends_at: NaiveDateTime, - pub published: bool, -} - -#[derive(Deserialize, Clone, Debug)] -pub struct NewCampaignInput { - pub organisation_id: i32, - pub name: String, - pub description: String, - pub starts_at: String, - pub ends_at: String, - pub published: bool, -} - -#[derive(Serialize)] -pub struct CampaignWithRoles { - pub campaign: Campaign, - pub roles: Vec, - pub questions: Vec, - pub applied_for: Vec<(i32, ApplicationStatus)>, -} - -impl CampaignWithRoles { - pub fn with_http_cover_image(mut self) -> Self { - self.campaign = self.campaign.with_http_cover_image(); - self - } -} - -impl Campaign { - pub fn get_all(conn: &PgConnection) -> Vec { - use crate::database::schema::campaigns::dsl::*; - - campaigns - .order(id.asc()) - .load(conn) - .unwrap_or_else(|_| vec![]) - } - - pub fn get_cover_image(conn: &PgConnection, campaign_id: i32) -> Option { - use crate::database::schema::campaigns::dsl::*; - - campaigns - .filter(id.eq(campaign_id)) - .select(cover_image) - .first(conn) - .unwrap() - } - - pub fn with_http_cover_image(mut self) -> Self { - self.cover_image = self - .cover_image - .map(|logo_uuid| get_http_image_path(ImageLocation::CAMPAIGNS, &logo_uuid)); - self - } - - pub fn set_cover_image(conn: &PgConnection, campaign_id: i32, new_cover_image: &str) -> String { - use crate::database::schema::campaigns::dsl::*; - - diesel::update(campaigns.find(campaign_id)) - .set(cover_image.eq(new_cover_image)) - .get_result::(conn) - .unwrap() - .cover_image - .unwrap() - } - - pub fn is_running(&self) -> bool { - let now = Utc::now().naive_utc(); - self.starts_at <= now && self.ends_at >= now - } - - /// return all campaigns that are live to all users - pub fn get_all_public_with_roles(conn: &PgConnection, user_id: i32) -> Vec { - use crate::database::schema::campaigns::dsl::*; - - let now = Utc::now().naive_utc(); - let campaigns_vec: Vec = campaigns - .filter( - starts_at - .le(now) - .and(published.eq(true)) - .and(ends_at.gt(now)), - ) - .order(id.asc()) - .load(conn) - .unwrap_or_else(|_| vec![]); - - Self::pack_roles_and_applied_to_into_campaigns_vec(conn, campaigns_vec, user_id) - } - - fn pack_roles_and_applied_to_into_campaigns_vec( - conn: &PgConnection, - campaigns_vec: Vec, - user_id: i32, - ) -> Vec { - campaigns_vec - .into_iter() - .map(|campaign| { - let campaign_roles = Role::get_all_from_campaign_id(&conn, campaign.id); - - let mut seen = HashSet::new(); - - let questions = campaign_roles - .iter() - .map(|x| Question::get_all_from_role_id(conn, x.id).into_iter()) - .flatten() - .filter(|x| { - if !seen.contains(&x.id) { - seen.insert(x.id); - true - } else { - false - } - }) - .collect(); - - let applied_for: Vec<(i32, ApplicationStatus)> = campaign_roles - .clone() - .into_iter() - .filter_map(|role| { - let app = Application::get_all_from_role_id(&conn, role.id) - .into_iter() - .filter(|app| app.user_id == user_id) - .next()?; - Some((role.id, app.status)) - }) - .collect(); - - CampaignWithRoles { - campaign, - roles: campaign_roles, - applied_for, - questions, - } - }) - .collect() - } - - // return all campaigns that are live and in the past - pub fn get_all_public_ended_with_roles( - conn: &PgConnection, - user_id: i32, - ) -> Vec { - use crate::database::schema::campaigns::dsl::*; - - let now = Utc::now().naive_utc(); - let campaigns_vec: Vec = campaigns - .filter(ends_at.lt(now).and(published.eq(true))) - .order(id.asc()) - .load(conn) - .unwrap_or_else(|_| vec![]); - - Self::pack_roles_and_applied_to_into_campaigns_vec(conn, campaigns_vec, user_id) - } - - pub fn get_all_from_org_id(conn: &PgConnection, organisation_id_val: i32) -> Vec { - use crate::database::schema::campaigns::dsl::*; - - campaigns - .filter(organisation_id.eq(organisation_id_val)) - .order(id.asc()) - .load(conn) - .unwrap_or_else(|_| vec![]) - } - - pub fn get_from_organisation_id( - conn: &PgConnection, - organisation_id_val: i32, - ) -> Vec { - use crate::database::schema::campaigns::dsl::*; - - campaigns - .filter(organisation_id.eq(organisation_id_val)) - .order(id.asc()) - .load(conn) - .unwrap_or_else(|_| vec![]) - } - - pub fn get_from_id(conn: &PgConnection, campaign_id: i32) -> Option { - use crate::database::schema::campaigns::dsl::*; - - campaigns.filter(id.eq(campaign_id)).first(conn).ok() - } - - pub fn update( - conn: &PgConnection, - campaign_id: i32, - update_campaign: &UpdateCampaignInput, - ) -> Option { - use crate::database::schema::campaigns::dsl::*; - - let update_changeset = UpdateCampaignChangeset { - name: update_campaign.name.clone(), - cover_image: update_campaign.cover_image.clone(), - description: update_campaign.description.clone(), - starts_at: NaiveDateTime::parse_from_str( - &update_campaign.starts_at, - "%Y-%m-%dT%H:%M:%S", - ) - .unwrap(), - ends_at: NaiveDateTime::parse_from_str(&update_campaign.ends_at, "%Y-%m-%dT%H:%M:%S") - .unwrap(), - published: update_campaign.published, - }; - - diesel::update(campaigns.filter(id.eq(campaign_id))) - .set(update_changeset) - .get_result(conn) - .ok() - } - - pub fn create(conn: &PgConnection, new_campaign: &NewCampaignInput) -> Option { - use crate::database::schema::campaigns::dsl::*; - - let new_campaign = NewCampaign { - organisation_id: new_campaign.organisation_id, - name: new_campaign.name.clone(), - cover_image: None, - description: new_campaign.description.clone(), - starts_at: NaiveDateTime::parse_from_str(&new_campaign.starts_at, "%Y-%m-%d %H:%M:%S") - .ok()?, - ends_at: NaiveDateTime::parse_from_str(&new_campaign.ends_at, "%Y-%m-%d %H:%M:%S") - .ok()?, - published: new_campaign.published, - }; - - if campaigns - .filter(organisation_id.eq(new_campaign.organisation_id)) - .filter(name.eq(&new_campaign.name)) - .first::(conn) - .is_ok() - { - return None; - } - - new_campaign.insert(conn) - } - - pub fn delete(conn: &PgConnection, campaign_id: i32) -> bool { - use crate::database::schema::campaigns::dsl::*; - - diesel::delete(campaigns.filter(id.eq(campaign_id))) - .execute(conn) - .is_ok() - } - - pub fn delete_deep(conn: &PgConnection, campaign_id: i32) -> Option<()> { - use crate::database::schema::roles::dsl::{campaign_id as dsl_role_campaign_id, roles}; - - if let Some(cover_image) = Campaign::get_cover_image(conn, campaign_id) { - remove_file(Path::new(&cover_image)).ok()?; - } - - let role_items: Vec = roles - .filter(dsl_role_campaign_id.eq(campaign_id)) - .load(conn) - .map_err(|x| eprintln!("error in delete deep: {x:?}")) - .ok()?; - - role_items.into_iter().for_each(|role| { - Role::delete_deep(conn, role.id); - }); - - if !Campaign::delete(conn, campaign_id) { - None - } else { - Some(()) - } - } -} - -impl NewCampaign { - pub fn insert(&self, conn: &PgConnection) -> Option { - use crate::database::schema::campaigns::dsl::*; - self.insert_into(campaigns).get_result(conn).ok() - } -} - -#[derive(Identifiable, Queryable, Serialize, Associations, Clone, PartialEq)] -#[belongs_to(Campaign)] -pub struct Role { - pub id: i32, - pub campaign_id: i32, - pub name: String, - pub description: Option, - pub min_available: i32, - pub max_available: i32, - pub finalised: bool, - pub created_at: NaiveDateTime, - pub updated_at: NaiveDateTime, -} - -#[derive(Insertable, AsChangeset, FromForm, Deserialize, Debug)] -#[table_name = "roles"] -pub struct RoleUpdate { - pub campaign_id: i32, - pub name: String, - pub description: Option, - pub min_available: i32, - pub max_available: i32, - pub finalised: bool, -} - -impl Role { - pub fn get_all(conn: &PgConnection) -> Vec { - use crate::database::schema::roles::dsl::*; - - roles.order(id.asc()).load(conn).unwrap_or_else(|_| vec![]) - } - - pub fn get_all_from_campaign_id(conn: &PgConnection, campaign_id_val: i32) -> Vec { - use crate::database::schema::roles::dsl::*; - - roles - .filter(campaign_id.eq(campaign_id_val)) - .order(id.asc()) - .load(conn) - .unwrap_or_else(|_| vec![]) - } - - pub fn get_from_name(conn: &PgConnection, role_name: &str) -> Option { - use crate::database::schema::roles::dsl::*; - - roles.filter(name.eq(role_name)).first(conn).ok() - } - - pub fn get_from_id(conn: &PgConnection, role_id: i32) -> Option { - use crate::database::schema::roles::dsl::*; - - roles.filter(id.eq(role_id)).first(conn).ok() - } - - pub fn update(conn: &PgConnection, role_id: i32, role_update: &RoleUpdate) -> Option { - use crate::database::schema::roles::dsl::*; - - diesel::update(roles.filter(id.eq(role_id))) - .set(role_update) - .get_result(conn) - .ok() - } - - pub fn delete(conn: &PgConnection, role_id: i32) -> bool { - use crate::database::schema::roles::dsl::*; - - diesel::delete(roles.filter(id.eq(role_id))) - .execute(conn) - .is_ok() - } - - pub fn delete_children(conn: &PgConnection, role: Role) -> Option<()> { - use diesel::pg::expression::dsl::any; - - let question_items: Vec = questions::table - .filter(any(questions::role_ids).eq(role.id)) - .load(conn) - .map_err(|x| { - eprintln!("error in delete_children: {x:?}"); - x - }) - .ok()?; - - diesel::delete(questions::table.filter(any(questions::role_ids).eq(role.id))) - .execute(conn) - .map_err(|x| { - eprintln!("error in delete_children: {x:?}"); - x - }) - .ok(); - - for question in question_items { - diesel::delete(answers::table.filter(answers::question_id.eq(question.id))) - .execute(conn) - .map_err(|x| { - eprintln!("error in delete_children: {x:?}"); - x - }) - .ok(); - } - - let application_items: Vec = applications::table - .filter(applications::role_id.eq(role.id)) - .load(conn) - .map_err(|x| { - eprintln!("error in delete_children: {x:?}"); - x - }) - .ok()?; - - for application in application_items { - Application::delete_deep(conn, application); - } - - diesel::delete(applications::table.filter(applications::role_id.eq(role.id))) - .execute(conn) - .map_err(|x| { - eprintln!("error in delete_children: {x:?}"); - x - }) - .ok(); - - Some(()) - } - - pub fn delete_deep(conn: &PgConnection, role_id: i32) -> Option<()> { - let questions = Question::get_all_from_role_id(conn, role_id); - let applications = Application::get_all_from_role_id(conn, role_id); - - questions.into_iter().for_each(|question| { - Question::delete_deep(conn, question.id); - }); - applications.into_iter().for_each(|application| { - Application::delete_deep(conn, application); - }); - - if Role::delete(conn, role_id) { - Some(()) - } else { - None - } - } -} - -impl RoleUpdate { - pub fn insert(&self, conn: &PgConnection) -> Option { - use crate::database::schema::roles::dsl::*; - - self.insert_into(roles).get_result(conn).ok() - } -} - -#[derive(Identifiable, Queryable, Associations, PartialEq, Serialize)] -#[belongs_to(Role)] -#[belongs_to(OrganisationUser, foreign_key = "user_id")] -pub struct Application { - pub id: i32, - pub user_id: i32, - pub role_id: i32, - pub status: ApplicationStatus, - pub private_status: ApplicationStatus, - pub created_at: NaiveDateTime, - pub updated_at: NaiveDateTime, -} - -#[derive(Insertable, FromForm, Deserialize)] -#[table_name = "applications"] -pub struct NewApplication { - pub user_id: i32, - pub role_id: i32, - pub status: ApplicationStatus, - pub private_status: ApplicationStatus, -} - -impl Application { - pub fn get_all(conn: &PgConnection) -> Vec { - use crate::database::schema::applications::dsl::*; - - applications - .order(id.asc()) - .load(conn) - .unwrap_or_else(|_| vec![]) - } - - pub fn get(app_id: i32, conn: &PgConnection) -> Option { - use crate::database::schema::applications::dsl::*; - - applications.filter(id.eq(app_id)).first(conn).ok() - } - - pub fn get_all_from_user_id(conn: &PgConnection, user_id_val: i32) -> Vec { - use crate::database::schema::applications::dsl::*; - - applications - .filter(user_id.eq(user_id_val)) - .order(id.asc()) - .load(conn) - .unwrap_or_else(|_| vec![]) - } - - pub fn get_all_from_role_id(conn: &PgConnection, role_id_val: i32) -> Vec { - use crate::database::schema::applications::dsl::*; - - applications - .filter(role_id.eq(role_id_val)) - .order(id.asc()) - .load(conn) - .unwrap_or_else(|_| vec![]) - } - - pub fn get_all_from_campaign_id(conn: &PgConnection, role_id_val: i32) -> Vec { - use crate::database::schema::applications::dsl::*; - - applications - .filter(role_id.eq(role_id_val)) - .order(id.asc()) - .load(conn) - .unwrap_or_else(|_| vec![]) - } - - pub fn delete(conn: &PgConnection, application_id: i32) -> bool { - use crate::database::schema::applications::dsl::*; - - diesel::delete(applications.filter(id.eq(application_id))) - .execute(conn) - .map_err(|x| { - eprintln!("error in delete application: {x:?}"); - x - }) - .is_ok() - } - - pub fn delete_deep(conn: &PgConnection, application: Application) -> Option<()> { - let ratings = Rating::get_all_from_application_id(conn, application.id); - let comments = Comment::get_all_from_application_id(conn, application.id); - let answers = Answer::get_all_from_application_id(conn, application.id); - - ratings.into_iter().for_each(|rating| { - Rating::delete_deep(conn, rating.id); - }); - comments.into_iter().for_each(|comment| { - Comment::delete_deep(conn, comment.id); - }); - answers.into_iter().for_each(|answer| { - Answer::delete_deep(conn, answer.id); - }); - - match Application::delete(conn, application.id) { - true => Some(()), - false => None, - } - } -} - -impl NewApplication { - pub fn insert(&self, conn: &PgConnection) -> Option { - use crate::database::schema::applications::dsl::*; - - self.insert_into(applications).get_result(conn).ok() - } -} - -#[derive(Identifiable, Queryable, PartialEq, Serialize, Debug, QueryableByName)] -#[table_name = "questions"] -pub struct Question { - pub id: i32, - pub role_ids: Vec, - pub title: String, - pub description: Option, - pub max_bytes: i32, - pub required: bool, - pub created_at: NaiveDateTime, - pub updated_at: NaiveDateTime, -} - -#[derive(Insertable, Serialize, Deserialize)] -#[table_name = "questions"] -pub struct NewQuestion { - pub role_ids: Vec, - pub title: String, - pub description: Option, - #[serde(default)] - pub max_bytes: i32, - pub required: bool, -} - -#[derive(Serialize)] -pub struct QuestionResponse { - pub id: i32, - pub role_ids: Vec, - pub title: String, - pub description: Option, - pub max_bytes: i32, - pub required: bool, -} - -impl std::convert::From for QuestionResponse { - fn from(question: Question) -> Self { - Self { - id: question.id, - role_ids: question.role_ids, - title: question.title, - description: question.description, - max_bytes: question.max_bytes, - required: question.required, - } - } -} - -#[derive(FromForm, AsChangeset, Deserialize)] -#[table_name = "questions"] -pub struct UpdateQuestionInput { - pub title: String, - pub description: Option, - pub max_bytes: i32, - pub required: bool, -} - -impl Question { - pub fn get_first_role(&self) -> i32 { - *self - .role_ids - .get(0) - .expect("Question should be for at least one role") - } - - pub fn update( - conn: &PgConnection, - question_id: i32, - update_question: UpdateQuestionInput, - ) -> Option<()> { - use crate::database::schema::questions::dsl::*; - - diesel::update(questions.filter(id.eq(question_id))) - .set(update_question) - .execute(conn) - .ok()?; - - Some(()) - } - - pub fn get_all_from_role_id(conn: &PgConnection, role_id_val: i32) -> Vec { - diesel::sql_query(&format!( - "select * from questions where {} = any(role_ids)", - role_id_val - )) - .load::(conn) - .unwrap_or_else(|_| vec![]) - } - - pub fn delete_all_from_role_id(conn: &PgConnection, role_id_val: i32) -> bool { - diesel::sql_query(&format!( - "delete from questions where {} = any(role_ids)", - role_id_val - )) - .execute(conn) - .is_ok() - } - - pub fn delete(conn: &PgConnection, question_id: i32) -> bool { - use crate::database::schema::questions::dsl::*; - - diesel::delete(questions.filter(id.eq(question_id))) - .execute(conn) - .is_ok() - } - - pub fn delete_deep(conn: &PgConnection, question_id: i32) -> bool { - Answer::get_all_from_question_id(conn, question_id) - .into_iter() - .for_each(|answer| { - Answer::delete_deep(conn, answer.id); - }); - - Question::delete(conn, question_id) - } - - pub fn get_from_id(conn: &PgConnection, question_id: i32) -> Option { - use crate::database::schema::questions::dsl::*; - - questions.filter(id.eq(question_id)).first(conn).ok() - } -} - -impl NewQuestion { - pub fn insert(&self, conn: &PgConnection) -> Option { - use crate::database::schema::questions::dsl::*; - - self.insert_into(questions).get_result(conn).ok() - } -} - -#[derive(Identifiable, Queryable, Associations, PartialEq, Serialize)] -#[belongs_to(Question)] -#[belongs_to(Application)] -pub struct Answer { - pub id: i32, - pub application_id: i32, - pub question_id: i32, - pub description: String, - pub created_at: NaiveDateTime, - pub updated_at: NaiveDateTime, -} - -#[derive(Insertable, Deserialize)] -#[table_name = "answers"] -pub struct NewAnswer { - pub application_id: i32, - pub question_id: i32, - pub description: String, -} - -impl Answer { - pub fn get_all(conn: &PgConnection) -> Vec { - use crate::database::schema::answers::dsl::*; - - answers - .order(id.asc()) - .load(conn) - .unwrap_or_else(|_| vec![]) - } - - pub fn get_all_from_application_id( - conn: &PgConnection, - application_id_val: i32, - ) -> Vec { - use crate::database::schema::answers::dsl::*; - - answers - .filter(application_id.eq(application_id_val)) - .order(id.asc()) - .load(conn) - .unwrap_or_else(|_| vec![]) - } - - pub fn get_all_from_question_id(conn: &PgConnection, question_id_val: i32) -> Vec { - use crate::database::schema::answers::dsl::*; - - answers - .filter(question_id.eq(question_id_val)) - .order(id.asc()) - .load(conn) - .unwrap_or_else(|_| vec![]) - } - - pub fn delete(conn: &PgConnection, answer_id_val: i32) -> bool { - use crate::database::schema::answers::dsl::*; - - diesel::delete(answers.filter(id.eq(answer_id_val))) - .execute(conn) - .is_ok() - } - - pub fn delete_deep(conn: &PgConnection, answer_id_val: i32) -> bool { - use crate::database::schema::answers::dsl::*; - - diesel::delete(answers.filter(id.eq(answer_id_val))) - .execute(conn) - .is_ok() - } -} - -impl NewAnswer { - pub fn insert(&self, conn: &PgConnection) -> Option { - use crate::database::schema::answers::dsl::*; - - self.insert_into(answers).get_result(conn).ok() - } -} - -#[derive(Identifiable, Queryable, Associations, PartialEq, Serialize)] -#[belongs_to(Application)] -#[belongs_to(OrganisationUser, foreign_key = "commenter_user_id")] -pub struct Comment { - pub id: i32, - pub application_id: i32, - pub commenter_user_id: i32, - pub description: String, - pub created_at: NaiveDateTime, - pub updated_at: NaiveDateTime, -} - -#[derive(Insertable)] -#[table_name = "comments"] -pub struct NewComment { - pub application_id: i32, - pub commenter_user_id: i32, - pub description: String, -} - -impl Comment { - pub fn get_from_id(conn: &PgConnection, comment_id: i32) -> Option { - use crate::database::schema::comments::dsl::*; - - comments.filter(id.eq(comment_id)).first(conn).ok() - } - - pub fn get_all(conn: &PgConnection) -> Vec { - use crate::database::schema::comments::dsl::*; - - comments - .order(id.asc()) - .load(conn) - .unwrap_or_else(|_| vec![]) - } - - pub fn get_all_from_application_id( - conn: &PgConnection, - application_id_val: i32, - ) -> Vec { - use crate::database::schema::comments::dsl::*; - - comments - .filter(application_id.eq(application_id_val)) - .order(id.asc()) - .load(conn) - .unwrap_or_else(|_| vec![]) - } - - pub fn delete(conn: &PgConnection, comment_id_val: i32) -> bool { - use crate::database::schema::comments::dsl::*; - - diesel::delete(comments.filter(id.eq(comment_id_val))) - .execute(conn) - .is_ok() - } - - pub fn delete_deep(conn: &PgConnection, comment_id_val: i32) -> bool { - use crate::database::schema::comments::dsl::*; - - diesel::delete(comments.filter(id.eq(comment_id_val))) - .execute(conn) - .is_ok() - } -} - -impl NewComment { - pub fn insert(&self, conn: &PgConnection) -> Option { - use crate::database::schema::comments::dsl::*; - - self.insert_into(comments).get_result(conn).ok() - } -} - -#[derive(Identifiable, Queryable, Associations, PartialEq, Serialize)] -#[belongs_to(Application)] -#[belongs_to(OrganisationUser, foreign_key = "rater_user_id")] -pub struct Rating { - pub id: i32, - pub application_id: i32, - pub rater_user_id: i32, - pub rating: i32, - pub created_at: NaiveDateTime, - pub updated_at: NaiveDateTime, -} - -#[derive(Insertable)] -#[table_name = "ratings"] -pub struct NewRating { - pub application_id: i32, - pub rater_user_id: i32, - pub rating: i32, -} - -impl Rating { - pub fn get_all(conn: &PgConnection) -> Vec { - use crate::database::schema::ratings::dsl::*; - - ratings - .order(id.asc()) - .load(conn) - .unwrap_or_else(|_| vec![]) - } - - pub fn get_all_from_application_id( - conn: &PgConnection, - application_id_val: i32, - ) -> Vec { - use crate::database::schema::ratings::dsl::*; - - ratings - .filter(application_id.eq(application_id_val)) - .order(id.asc()) - .load(conn) - .unwrap_or_else(|_| vec![]) - } - - pub fn get_all_from_rater_user_id(conn: &PgConnection, user_id_val: i32) -> Vec { - use crate::database::schema::ratings::dsl::*; - - ratings - .filter(rater_user_id.eq(user_id_val)) - .order(id.asc()) - .load(conn) - .unwrap_or_else(|_| vec![]) - } - - pub fn delete(conn: &PgConnection, rating_id_val: i32) -> bool { - use crate::database::schema::ratings::dsl::*; - diesel::delete(ratings.filter(id.eq(rating_id_val))) - .execute(conn) - .is_ok() - } - - pub fn delete_deep(conn: &PgConnection, rating_id_val: i32) -> bool { - use crate::database::schema::ratings::dsl::*; - diesel::delete(ratings.filter(id.eq(rating_id_val))) - .execute(conn) - .is_ok() - } -} - -impl NewRating { - pub fn insert(&self, conn: &PgConnection) -> Option { - use crate::database::schema::ratings::dsl::*; - - self.insert_into(ratings).get_result(conn).ok() - } -} - -#[derive(Serialize)] -pub struct GetQuestionsResponse { - pub questions: Vec, -} - -#[derive(Serialize)] -pub struct CampaignInfo { - pub id: i32, - pub name: String, - pub cover_image: Option, - pub starts_at: NaiveDateTime, - pub ends_at: NaiveDateTime, -} - -impl std::convert::From for CampaignInfo { - fn from(campaign: Campaign) -> Self { - Self { - id: campaign.id, - name: campaign.name, - cover_image: campaign - .cover_image - .map(|image| get_http_image_path(ImageLocation::CAMPAIGNS, &image)), - starts_at: campaign.starts_at, - ends_at: campaign.ends_at, - } - } -} - -#[derive(Serialize)] -pub struct OrganisationUserInfo { - pub id: i32, - pub display_name: String, - pub role: AdminLevel, -} - -impl OrganisationUserInfo { - pub fn get_all_from_organisation_id( - conn: &PgConnection, - organisation_id_val: i32, - ) -> Vec { - use crate::database::schema::organisation_users::dsl::*; - - organisation_users - .filter(organisation_id.eq(organisation_id_val)) - .order(id.asc()) - .load(conn) - .unwrap_or_else(|_| vec![]) - .into_iter() - .map(|o: OrganisationUser| { - let user = User::get_from_id(conn, o.user_id).unwrap(); - Self { - id: o.user_id, - display_name: user.display_name, - role: o.admin_level, - } - }) - .collect() - } -} - -#[derive(Serialize)] -pub struct OrganisationInfo { - pub id: i32, - pub name: String, - pub logo: Option, - pub members: Vec, - pub campaigns: Vec, -} - -impl OrganisationInfo { - pub fn new(organisation_id: i32, conn: &PgConnection) -> Self { - let organisation = Organisation::get_from_id(conn, organisation_id).unwrap(); - Self { - id: organisation.id, - name: organisation.name, - logo: organisation - .logo - .map(|logo_uuid| get_http_image_path(ImageLocation::ORGANISATIONS, &logo_uuid)), - members: OrganisationUserInfo::get_all_from_organisation_id(conn, organisation.id), - campaigns: Campaign::get_all_from_org_id(conn, organisation.id) - .into_iter() - .map(|c: Campaign| CampaignInfo::from(c)) - .collect(), - } - } -} - -#[derive(Serialize)] -pub struct AdminInfoResponse { - pub organisations: Vec, -} diff --git a/backend/server/src/database/schema.rs b/backend/server/src/database/schema.rs deleted file mode 100644 index a5a526d4f..000000000 --- a/backend/server/src/database/schema.rs +++ /dev/null @@ -1,197 +0,0 @@ -use diesel_derive_enum::DbEnum; -use rocket::FromFormField; -use serde::{Deserialize, Serialize}; - -#[derive(Debug, DbEnum, PartialEq, FromFormField, Serialize, Deserialize, Clone, Copy)] -#[DbValueStyle = "PascalCase"] -pub enum ApplicationStatus { - Draft, - Pending, - Rejected, - Success, -} - -#[derive(Debug, DbEnum, PartialEq, Serialize, Deserialize, Clone, Copy)] -#[DbValueStyle = "PascalCase"] -pub enum AdminLevel { - ReadOnly = 1, - Director, - Admin, -} - -impl AdminLevel { - pub fn geq(self, other: Self) -> bool { - self as i32 >= other as i32 - } -} - -#[derive(Debug, DbEnum, PartialEq, Serialize, Deserialize, Clone, Copy)] -#[DbValueStyle = "PascalCase"] -pub enum UserGender { - Female, - Male, - Unspecified, -} - -table! { - answers (id) { - id -> Int4, - application_id -> Int4, - question_id -> Int4, - description -> Text, - created_at -> Timestamp, - updated_at -> Timestamp, - } -} - -table! { - use diesel::sql_types::*; - use super::ApplicationStatusMapping; - - applications (id) { - id -> Int4, - user_id -> Int4, - role_id -> Int4, - status -> ApplicationStatusMapping, - private_status -> ApplicationStatusMapping, - created_at -> Timestamp, - updated_at -> Timestamp, - } -} - -table! { - campaigns (id) { - id -> Int4, - organisation_id -> Int4, - name -> Text, - cover_image -> Nullable, - description -> Text, - starts_at -> Timestamp, - ends_at -> Timestamp, - published -> Bool, - created_at -> Timestamp, - updated_at -> Timestamp, - } -} - -table! { - comments (id) { - id -> Int4, - application_id -> Int4, - commenter_user_id -> Int4, - description -> Text, - created_at -> Timestamp, - updated_at -> Timestamp, - } -} - -table! { - use diesel::sql_types::*; - use super::AdminLevelMapping; - - organisation_users (id) { - id -> Int4, - user_id -> Int4, - organisation_id -> Int4, - admin_level -> AdminLevelMapping, - created_at -> Timestamp, - updated_at -> Timestamp, - } -} - -table! { - organisations (id) { - id -> Int4, - name -> Text, - logo -> Nullable, - created_at -> Timestamp, - updated_at -> Timestamp, - } -} - -table! { - use diesel::sql_types::*; - - questions (id) { - id -> Int4, - role_ids -> Array, - title -> Text, - description -> Nullable, - max_bytes -> Int4, - required -> Bool, - created_at -> Timestamp, - updated_at -> Timestamp, - } -} - -table! { - ratings (id) { - id -> Int4, - application_id -> Int4, - rater_user_id -> Int4, - rating -> Int4, - created_at -> Timestamp, - updated_at -> Timestamp, - } -} - -table! { - roles (id) { - id -> Int4, - campaign_id -> Int4, - name -> Text, - description -> Nullable, - min_available -> Int4, - max_available -> Int4, - finalised -> Bool, - created_at -> Timestamp, - updated_at -> Timestamp, - } -} - -table! { - use diesel::sql_types::*; - use super::UserGenderMapping; - - users (id) { - id -> Int4, - email -> Text, - zid -> Text, - display_name -> Text, - degree_name -> Text, - degree_starting_year -> Int4, - gender -> UserGenderMapping, - pronouns -> Text, - superuser -> Bool, - created_at -> Timestamp, - updated_at -> Timestamp, - } -} - -joinable!(answers -> applications (application_id)); -joinable!(answers -> questions (question_id)); -joinable!(applications -> roles (role_id)); -joinable!(applications -> users (user_id)); -joinable!(campaigns -> organisations (organisation_id)); -joinable!(comments -> applications (application_id)); -joinable!(comments -> users (commenter_user_id)); -joinable!(organisation_users -> organisations (organisation_id)); -joinable!(organisation_users -> users (user_id)); -// TODO: can probably make this work to auto join but idk how -// joinable!(questions -> roles (role_id)); -joinable!(ratings -> applications (application_id)); -joinable!(ratings -> users (rater_user_id)); -joinable!(roles -> campaigns (campaign_id)); - -allow_tables_to_appear_in_same_query!( - answers, - applications, - campaigns, - comments, - organisation_users, - organisations, - questions, - ratings, - roles, - users, -); diff --git a/backend/server/src/diesel.toml b/backend/server/src/diesel.toml deleted file mode 100644 index bfb01bccf..000000000 --- a/backend/server/src/diesel.toml +++ /dev/null @@ -1,5 +0,0 @@ -# For documentation on how to configure this file, -# see diesel.rs/guides/configuring-diesel-cli - -[print_schema] -file = "src/database/schema.rs" diff --git a/backend/server/src/error.rs b/backend/server/src/error.rs deleted file mode 100644 index b73a1cb17..000000000 --- a/backend/server/src/error.rs +++ /dev/null @@ -1,16 +0,0 @@ -use rocket::http::Status; -use rocket::request::Request; -use rocket::response::{self, Responder}; -use rocket::serde::{json::Json, Serialize}; - -pub struct JsonErr(pub T, pub Status); - -impl<'r, T: Serialize> Responder<'r, 'r> for JsonErr { - fn respond_to(self, r: &Request) -> response::Result<'r> { - let json_self = Json(self.0); - json_self.respond_to(r).map(|mut r| { - r.set_status(self.1); - r - }) - } -} diff --git a/backend/server/src/guard/mod.rs b/backend/server/src/guard/mod.rs deleted file mode 100644 index e97ade673..000000000 --- a/backend/server/src/guard/mod.rs +++ /dev/null @@ -1,88 +0,0 @@ -use rocket::{ - http::Status, - request::{self, FromRequest, Outcome}, - Request, -}; - -use crate::{ - auth::{Auth, AuthError}, - database::{ - models::{SuperUser, User}, - Database, - }, -}; - -#[derive(Debug)] -pub enum UserError { - AuthError(AuthError), - AccountNoLongerExists, -} - -#[rocket::async_trait] -impl<'r> FromRequest<'r> for User { - type Error = UserError; - - async fn from_request(request: &'r Request<'_>) -> request::Outcome { - let auth = match request.guard::().await { - Outcome::Success(auth) => auth, - Outcome::Failure((status, error)) => { - return Outcome::Failure((status, UserError::AuthError(error))) - } - Outcome::Forward(forward) => return Outcome::Forward(forward), - }; - - let database = request.guard::().await.unwrap(); - - let user_id = auth.jwt.user_id; - let user = database - .run(move |conn| User::get_from_id(conn, user_id as i32)) - .await; - - match user { - Some(user) => Outcome::Success(user), - None => Outcome::Failure(( - Status::InternalServerError, - UserError::AccountNoLongerExists, - )), - } - } -} - -#[rocket::async_trait] -impl<'r> FromRequest<'r> for SuperUser { - type Error = UserError; - - async fn from_request(request: &'r Request<'_>) -> request::Outcome { - let auth = match request.guard::().await { - Outcome::Success(auth) => auth, - Outcome::Failure((status, error)) => { - return Outcome::Failure((status, UserError::AuthError(error))) - } - Outcome::Forward(forward) => return Outcome::Forward(forward), - }; - - let database = request.guard::().await.unwrap(); - - let user_id = auth.jwt.user_id; - let user = database - .run(move |conn| User::get_from_id(conn, user_id as i32)) - .await; - - match user { - Some(user) => { - if user.superuser { - Outcome::Success(SuperUser::new(user)) - } else { - Outcome::Failure(( - Status::Forbidden, - UserError::AuthError(AuthError::NotSuperUser), - )) - } - } - None => Outcome::Failure(( - Status::InternalServerError, - UserError::AccountNoLongerExists, - )), - } - } -} diff --git a/backend/server/src/images.rs b/backend/server/src/images.rs deleted file mode 100644 index c7255beb4..000000000 --- a/backend/server/src/images.rs +++ /dev/null @@ -1,86 +0,0 @@ -use image::{io::Reader as ImageReader, DynamicImage, ImageError}; -use rocket::{data::ToByteUnit, Data}; -use std::{ - fs, - io::{self, Cursor}, - path::{Path, PathBuf}, -}; -use strum::{EnumIter, IntoEnumIterator}; -use webp::Encoder; - -pub enum ImageDecodeError { - ImageError(ImageError), - IoError(io::Error), -} - -impl From for ImageDecodeError { - fn from(error: ImageError) -> Self { - ImageDecodeError::ImageError(error) - } -} - -impl From for ImageDecodeError { - fn from(error: io::Error) -> Self { - ImageDecodeError::IoError(error) - } -} - -pub fn try_decode_bytes(bytes: Vec) -> Result { - ImageReader::new(Cursor::new(bytes)) - .with_guessed_format()? - .decode() -} - -#[rustfmt::skip] -pub async fn try_decode_data(data: Data<'_>) -> Result { - data.open(5.mebibytes()).into_bytes().await.map(|bytes| try_decode_bytes(bytes.to_vec())).map_err(|e| e.into()).and_then(|v| v.map_err(|e| e.into())) -} - -const HTTP_IMAGE_BASE_PATH: &str = "/api/static/images/"; -pub const IMAGE_BASE_PATH: &str = "./images/"; - -#[derive(EnumIter)] -pub enum ImageLocation { - CAMPAIGNS, - ORGANISATIONS, -} - -pub fn image_location_to_string(location: ImageLocation) -> String { - match location { - ImageLocation::CAMPAIGNS => "campaigns/", - ImageLocation::ORGANISATIONS => "organisations/", - } - .to_string() -} - -pub fn save_image( - image: DynamicImage, - location: ImageLocation, - image_uuid: &str, -) -> std::io::Result { - ImageLocation::iter().for_each(|location| { - fs::create_dir_all(Path::new(IMAGE_BASE_PATH).join(image_location_to_string(location))) - .ok(); - }); - - let path = get_image_path(location, image_uuid); - - let encoder = Encoder::from_image(&image).unwrap(); - let webp = encoder.encode(80.0); - std::fs::write(&path, &*webp).map(|_| path) -} - -pub fn get_image_path(location: ImageLocation, image_uuid: &str) -> PathBuf { - Path::new(IMAGE_BASE_PATH) - .join(image_location_to_string(location)) - .join(image_uuid) -} - -pub fn get_http_image_path(location: ImageLocation, image_uuid: &str) -> String { - Path::new(HTTP_IMAGE_BASE_PATH) - .join(image_location_to_string(location)) - .join(image_uuid) - .to_str() - .unwrap() - .to_string() -} diff --git a/backend/server/src/lib.rs b/backend/server/src/lib.rs deleted file mode 100644 index 80b721c5e..000000000 --- a/backend/server/src/lib.rs +++ /dev/null @@ -1,20 +0,0 @@ -#[macro_use] -extern crate diesel; - -pub mod admin; -pub mod application; -pub mod auth; -pub mod campaigns; -pub mod comment; -pub mod cors; -pub mod database; -pub mod error; -pub mod guard; -pub mod images; -pub mod organisation; -pub mod permissions; -pub mod question; -pub mod role; -pub mod state; -pub mod static_resources; -pub mod user; diff --git a/backend/server/src/organisation.rs b/backend/server/src/organisation.rs deleted file mode 100644 index 7088947df..000000000 --- a/backend/server/src/organisation.rs +++ /dev/null @@ -1,375 +0,0 @@ -use crate::error::JsonErr; -use crate::images::get_image_path; -use crate::{ - database::{ - models::{ - Campaign, NewOrganisation, NewOrganisationUser, Organisation, OrganisationUser, - SuperUser, User, - }, - schema::AdminLevel, - Database, - }, - images::{get_http_image_path, save_image, try_decode_data, ImageLocation}, -}; -use chrono::NaiveDateTime; -use rocket::{ - data::Data, - delete, get, - http::Status, - post, put, - serde::{json::Json, Deserialize, Serialize}, -}; -use std::collections::HashMap; -use std::fs::remove_file; -use uuid::Uuid; - -#[derive(Serialize)] -pub enum NewOrgError { - OrgNameAlreadyExists, - FailedToJoin, -} - -#[derive(Serialize)] -pub enum OrgError { - OrgNotFound, - InsufficientPerms, - UserIsNotInOrg, - UserNotFound, - UserAlreadyInOrg, - Unknown, -} - -#[post("/", data = "")] -pub async fn new( - organisation: Json, - user: SuperUser, - db: Database, -) -> Result, JsonErr> { - db.run(move |conn| { - let org = NewOrganisation::insert(&organisation, &conn) - .ok_or(JsonErr(NewOrgError::OrgNameAlreadyExists, Status::NotFound))?; - - let org_user = NewOrganisationUser { - user_id: user.user().id, - organisation_id: org.id, - admin_level: AdminLevel::Admin, - }; - - org_user - .insert(conn) - .ok_or(JsonErr(NewOrgError::FailedToJoin, Status::Forbidden))?; - - Ok(Json(org)) - }) - .await -} - -// ============ /organisation/ ============ - -#[get("/")] -pub async fn get_from_id( - org_id: i32, - _user: User, - db: Database, -) -> Result, JsonErr> { - db.run(move |conn| { - Organisation::get_from_id(&conn, org_id) - .ok_or(JsonErr(OrgError::OrgNotFound, Status::NotFound)) - .map(|mut v| { - v.logo = v - .logo - .map(|logo_uuid| get_http_image_path(ImageLocation::ORGANISATIONS, &logo_uuid)); - Json(v) - }) - }) - .await -} - -#[get("/", data = "")] -pub async fn get_from_ids( - orgs: Json>, - _user: User, - db: Database, -) -> Result>, JsonErr> { - db.run(move |conn| { - let mut res = HashMap::with_capacity(orgs.len()); - - for id in orgs.into_inner() { - res.insert( - id, - Organisation::get_from_id(&conn, id) - .ok_or(JsonErr(OrgError::OrgNotFound, Status::NotFound))?, - ); - } - - Ok(Json(res)) - }) - .await -} - -#[delete("/")] -pub async fn delete(org_id: i32, _user: SuperUser, db: Database) -> Result<(), JsonErr> { - db.run(move |conn| { - Organisation::delete_deep(&conn, org_id) - .ok_or(JsonErr(OrgError::OrgNotFound, Status::NotFound)) - }) - .await -} - -// ============ /organisation//superusers ============ - -#[get("//superusers")] -pub async fn get_admins( - org_id: i32, - _user: User, - db: Database, -) -> Result>, JsonErr> { - let res = db - .run(move |conn| Organisation::get_admin_ids(&conn, org_id)) - .await; - - match res { - Some(ids) => Ok(Json(ids)), - None => Err(JsonErr(OrgError::OrgNotFound, Status::NotFound)), - } -} - -#[derive(Serialize)] -pub enum LogoError { - Unauthorized, - ImageDeletionFailure, - ImageStoreFailure, -} - -#[put("//logo", data = "")] -pub async fn set_logo( - org_id: i32, - user: User, - db: Database, - image: Data<'_>, -) -> Result, JsonErr> { - db.run(move |conn| { - OrganisationUser::organisation_admin_level(org_id, user.id, &conn) - .is_at_least_director() - .check() - .or_else(|_| Err(JsonErr(LogoError::Unauthorized, Status::Forbidden))) - }) - .await?; - - let old_logo_uuid = db - .run(move |conn| Organisation::get_logo(&conn, org_id)) - .await; - let logo_uuid = Uuid::new_v4().as_hyphenated().to_string() + ".webp"; - - let image = try_decode_data(image).await.or_else(|_| { - Err(JsonErr( - LogoError::ImageDeletionFailure, - Status::InternalServerError, - )) - })?; - - save_image(image, ImageLocation::ORGANISATIONS, &logo_uuid) - .map_err(|_| JsonErr(LogoError::ImageStoreFailure, Status::InternalServerError))?; - - let logo_uuid_clone = logo_uuid.clone(); - - db.run(move |conn| Organisation::set_logo(&conn, org_id, &logo_uuid_clone)) - .await; - - if let Some(uuid) = old_logo_uuid { - remove_file(get_image_path(ImageLocation::ORGANISATIONS, &uuid)).ok(); - } - - Ok(Json(get_http_image_path( - ImageLocation::ORGANISATIONS, - &logo_uuid, - ))) -} - -#[put("//admins", data = "")] -pub async fn set_admins( - org_id: i32, - user: User, - db: Database, - admins: Json>, -) -> Result, JsonErr> { - let res = db - .run(move |conn| Organisation::get_admin_ids(&conn, org_id)) - .await; - - match res { - Some(ids) => { - if !ids.contains(&user.id) { - return Err(JsonErr(OrgError::InsufficientPerms, Status::Forbidden)); - } else { - db.run(move |conn| Organisation::set_admins(&conn, org_id, &admins)) - .await; - Ok(Json(())) - } - } - - None => Err(JsonErr(OrgError::OrgNotFound, Status::NotFound)), - } -} - -#[get("//is_admin")] -pub async fn is_admin(org_id: i32, user: User, db: Database) -> Json { - let res = db - .run(move |conn| Organisation::get_admin_ids(&conn, org_id)) - .await; - - match res { - Some(ids) => Json(ids.contains(&user.id) || user.superuser), - None => Json(false), - } -} - -#[derive(Serialize)] -pub struct CampaignResponse { - pub id: i32, - pub name: String, - pub cover_image: Option, - pub description: String, - pub starts_at: NaiveDateTime, - pub ends_at: NaiveDateTime, - pub published: bool, -} - -impl std::convert::From for CampaignResponse { - fn from(campaign: Campaign) -> Self { - Self { - id: campaign.id, - name: campaign.name, - cover_image: campaign - .cover_image - .map(|image| get_http_image_path(ImageLocation::CAMPAIGNS, &image)), - description: campaign.description, - starts_at: campaign.starts_at, - ends_at: campaign.ends_at, - published: campaign.published, - } - } -} - -#[derive(Serialize)] -pub struct GetCampaignsResponse { - campaigns: Vec, -} - -#[get("//campaigns")] -pub async fn get_associated_campaigns( - org_id: i32, - user: User, - db: Database, -) -> Json { - db.run(move |conn| { - let is_director = OrganisationUser::organisation_admin_level(org_id, user.id, conn) - .is_at_least_director() - .check() - .is_ok(); - - Json(GetCampaignsResponse { - campaigns: Campaign::get_all_from_org_id(conn, org_id) - .into_iter() - .filter(|v| v.published || is_director) - .map(CampaignResponse::from) - .collect(), - }) - }) - .await -} - -#[derive(Serialize, Deserialize)] -pub struct EmailInvite { - pub email: String, - pub admin_level: AdminLevel, -} - -#[post("//invite", data = "")] -pub async fn invite_email( - organisation_id: i32, - input: Json, - user: User, - db: Database, -) -> Result<(), JsonErr> { - let EmailInvite { email, admin_level } = input.into_inner(); - db.run(move |conn| { - let mut level = OrganisationUser::organisation_admin_level(organisation_id, user.id, conn) - .check() - .map_err(|_| JsonErr(OrgError::InsufficientPerms, Status::Forbidden))? - .0; - - if user.superuser { - level = AdminLevel::Admin; - } - - let invitee = User::get_from_email(conn, &email) - .ok_or(JsonErr(OrgError::UserNotFound, Status::NotFound))?; - - if level.geq(admin_level) { - let new_user = NewOrganisationUser { - user_id: invitee.id, - organisation_id, - admin_level, - }; - - new_user - .insert(conn) - .map(|_| ()) - .ok_or(JsonErr(OrgError::UserAlreadyInOrg, Status::NotAcceptable)) - } else { - Err(JsonErr(OrgError::InsufficientPerms, Status::Forbidden)) - } - }) - .await -} - -#[post("//invite/", data = "")] -pub async fn invite_uid( - organisation_id: i32, - admin_level: Json, - user_id: i32, - user: User, - db: Database, -) -> Result<(), JsonErr> { - db.run(move |conn| { - let mut level = OrganisationUser::organisation_admin_level(organisation_id, user.id, conn) - .check() - .map_err(|_| JsonErr(OrgError::InsufficientPerms, Status::Forbidden))? - .0; - - if user.superuser { - level = AdminLevel::Admin; - } - - let admin_level = admin_level.into_inner(); - - if level.geq(admin_level) { - match OrganisationUser::get(conn, organisation_id, user_id) { - Some(u) => { - if u.admin_level.geq(u.admin_level) { - Err(JsonErr(OrgError::InsufficientPerms, Status::Forbidden)) - } else { - u.update_admin_level(conn, admin_level) - .ok_or(JsonErr(OrgError::Unknown, Status::InternalServerError)) - } - } - None => { - let new_user = NewOrganisationUser { - user_id, - organisation_id, - admin_level, - }; - - new_user - .insert(conn) - .map(|_| ()) - .ok_or(JsonErr(OrgError::UserAlreadyInOrg, Status::NotAcceptable)) - } - } - } else { - Err(JsonErr(OrgError::InsufficientPerms, Status::Forbidden)) - } - }) - .await -} diff --git a/backend/server/src/permissions.rs b/backend/server/src/permissions.rs deleted file mode 100644 index 2b23abdf2..000000000 --- a/backend/server/src/permissions.rs +++ /dev/null @@ -1,254 +0,0 @@ -use crate::database::models::OrganisationUser; -use crate::database::schema::*; -use diesel::{ - expression_methods::ExpressionMethods, query_dsl::QueryDsl, JoinOnDsl, PgConnection, - RunQueryDsl, -}; - -/* -Permission Documentation - -The implmentation below is designed to be used in this pattern: - - db.run(move |conn| { - let campaign = Campaign::get_from_id(conn, campaign_id) - .ok_or_else(|| Json(RolesError::CampaignNotFound))?; - - OrganisationUser::campaign_admin_level(campaign_id, user.id, &conn) - .is_at_least_director() - .and(campaign.draft) // is at least director AND campaign is a draft - .check() - .or_else(|_| Err(Jsorganisation_users::on(RolesError::Unauthorized)))?; - }).await - -This allows you to search for different admin levels while keeping everything in one place. - - -Note on repeated code in this file: - -I originally wanted to do a dynamic set of inner joins, then execute in a pattern like this: -(this would have been implemented with BoxedExpression) - - db.run(move |conn| { - let campaign = Campaign::get_from_id(conn, campaign_id) - .ok_or_else(|| Json(RolesError::CampaignNotFound))?; - - OrganisationUser::campaign_admin_level(campaign_id, user.id) - .is_at_least_director() - .and(campaign.draft) // is at least director AND campaign is a draft - .check(&conn) - .or_else(|_| Err(Json(RolesError::Unauthorized)))?; - }).await - -However, diesel doesn't yet support boxed queries with inner joins (only single tables) -At the point at which this is supported, this file can be cleaned up massively and the above -syntax can be implemented (oh woe the youth of the rust language) -*/ - -pub enum PermissionError { - Unauthorized, - ConditionNotMet, -} - -pub struct AdminLevelUser { - // (admin_level, is_superuser) - res: Result<(AdminLevel, bool), PermissionError>, -} - -impl AdminLevelUser { - pub fn is_at_least_director(self) -> AdminLevelUser { - match self.res { - Ok((_, true)) | Ok((AdminLevel::Admin, false)) | Ok((AdminLevel::Director, false)) => { - self - } - _ => AdminLevelUser { - res: Err(PermissionError::Unauthorized), - }, - } - } - - pub fn is_admin(self) -> AdminLevelUser { - match self.res { - Ok((_, true)) | Ok((AdminLevel::Admin, false)) => self, - _ => AdminLevelUser { - res: Err(PermissionError::Unauthorized), - }, - } - } - - pub fn is_superuser(self) -> AdminLevelUser { - match self.res { - Ok((_, true)) => self, - _ => AdminLevelUser { - res: Err(PermissionError::Unauthorized), - }, - } - } - - pub fn and(self, condition: bool) -> AdminLevelUser { - match condition { - true => self, - false => AdminLevelUser { - res: Err(PermissionError::ConditionNotMet), - }, - } - } - - pub fn or(self, condition: bool) -> AdminLevelUser { - match condition { - true => self, - false => match self.res { - Ok((_, _)) => self, - _ => AdminLevelUser { - res: Err(PermissionError::ConditionNotMet), - }, - }, - } - } - - pub fn check(self) -> Result<(AdminLevel, bool), PermissionError> { - self.res - } -} - -impl std::convert::From> for AdminLevelUser { - fn from(res: Result<(AdminLevel, bool), PermissionError>) -> Self { - AdminLevelUser { res } - } -} - -fn is_superuser(user_id: i32, conn: &PgConnection) -> bool { - match users::table - .filter(users::id.eq(user_id)) - .select(users::superuser) - .first(conn) - .ok() - { - Some(true) => true, - _ => false, - } -} - -impl OrganisationUser { - pub fn organisation_admin_level( - org_id: i32, - user_id: i32, - conn: &PgConnection, - ) -> AdminLevelUser { - if is_superuser(user_id, conn) { - return AdminLevelUser { - res: Ok((AdminLevel::Admin, true)), - }; - } - organisation_users::table - .filter(organisation_users::organisation_id.eq(org_id)) - .inner_join(users::table.on(users::id.eq(organisation_users::user_id))) - .filter(users::id.eq(user_id)) - .select((organisation_users::admin_level, users::superuser)) - .first(conn) - .or_else(|_| Err(PermissionError::Unauthorized)) - .into() - } - - pub fn campaign_admin_level( - campaign_id: i32, - user_id: i32, - conn: &PgConnection, - ) -> AdminLevelUser { - if is_superuser(user_id, conn) { - return AdminLevelUser { - res: Ok((AdminLevel::Admin, true)), - }; - } - campaigns::table - .filter(campaigns::id.eq(campaign_id)) - .inner_join(organisations::table.on(organisations::id.eq(campaigns::organisation_id))) - .inner_join( - organisation_users::table - .on(organisation_users::organisation_id.eq(organisations::id)), - ) - .inner_join(users::table.on(users::id.eq(organisation_users::user_id))) - .filter(users::id.eq(user_id)) - .select((organisation_users::admin_level, users::superuser)) - .first(conn) - .or_else(|_| Err(PermissionError::Unauthorized)) - .into() - } - - pub fn application_admin_level( - application_id: i32, - user_id: i32, - conn: &PgConnection, - ) -> AdminLevelUser { - if is_superuser(user_id, conn) { - return AdminLevelUser { - res: Ok((AdminLevel::Admin, true)), - }; - } - applications::table - .filter(applications::id.eq(application_id)) - .inner_join(roles::table.on(roles::id.eq(applications::role_id))) - .inner_join(campaigns::table.on(campaigns::id.eq(roles::campaign_id))) - .inner_join(organisations::table.on(organisations::id.eq(campaigns::organisation_id))) - .inner_join( - organisation_users::table - .on(organisation_users::organisation_id.eq(organisations::id)), - ) - .inner_join(users::table.on(users::id.eq(organisation_users::user_id))) - .filter(users::id.eq(user_id)) - .select((organisation_users::admin_level, users::superuser)) - .first(conn) - .or_else(|_| Err(PermissionError::Unauthorized)) - .into() - } - - pub fn role_admin_level(role_id: i32, user_id: i32, conn: &PgConnection) -> AdminLevelUser { - if is_superuser(user_id, conn) { - return AdminLevelUser { - res: Ok((AdminLevel::Admin, true)), - }; - } - roles::table - .filter(roles::id.eq(role_id)) - .inner_join(campaigns::table.on(campaigns::id.eq(roles::campaign_id))) - .inner_join(organisations::table.on(organisations::id.eq(campaigns::organisation_id))) - .inner_join( - organisation_users::table - .on(organisation_users::organisation_id.eq(organisations::id)), - ) - .inner_join(users::table.on(users::id.eq(organisation_users::user_id))) - .filter(users::id.eq(user_id)) - .select((organisation_users::admin_level, users::superuser)) - .first(conn) - .or_else(|_| Err(PermissionError::Unauthorized)) - .into() - } - - pub fn comment_admin_level( - comment_id: i32, - user_id: i32, - conn: &PgConnection, - ) -> AdminLevelUser { - if is_superuser(user_id, conn) { - return AdminLevelUser { - res: Ok((AdminLevel::Admin, true)), - }; - } - comments::table - .filter(comments::id.eq(comment_id)) - .inner_join(applications::table.on(applications::id.eq(comments::application_id))) - .inner_join(roles::table.on(roles::id.eq(applications::role_id))) - .inner_join(campaigns::table.on(campaigns::id.eq(roles::campaign_id))) - .inner_join(organisations::table.on(organisations::id.eq(campaigns::organisation_id))) - .inner_join( - organisation_users::table - .on(organisation_users::organisation_id.eq(organisations::id)), - ) - .inner_join(users::table.on(users::id.eq(organisation_users::user_id))) - .filter(users::id.eq(user_id)) - .select((organisation_users::admin_level, users::superuser)) - .first(conn) - .or_else(|_| Err(PermissionError::Unauthorized)) - .into() - } -} diff --git a/backend/server/src/question.rs b/backend/server/src/question.rs deleted file mode 100644 index d45bc56f3..000000000 --- a/backend/server/src/question.rs +++ /dev/null @@ -1,113 +0,0 @@ -use crate::database::{ - models::{ - Campaign, OrganisationUser, Question, QuestionResponse, Role, UpdateQuestionInput, User, - }, - Database, -}; -use crate::error::JsonErr; - -use rocket::{ - delete, get, - http::Status, - put, - serde::{json::Json, Serialize}, -}; - -use std::convert::From; - -#[derive(Serialize)] -pub enum QuestionError { - QuestionNotFound, - UpdateFailed, - InsufficientPermissions, -} - -// TODO: may be useless function, also awfully inefficient. -#[get("/")] -pub async fn get_question( - user: User, - db: Database, - question_id: i32, -) -> Result, JsonErr> { - db.run(move |conn| { - let q = Question::get_from_id(&conn, question_id) - .ok_or(JsonErr(QuestionError::QuestionNotFound, Status::NotFound))?; - let r = Role::get_from_id(&conn, q.get_first_role()) - .ok_or(JsonErr(QuestionError::QuestionNotFound, Status::NotFound))?; - let c = Campaign::get_from_id(&conn, r.campaign_id) - .ok_or(JsonErr(QuestionError::QuestionNotFound, Status::NotFound))?; - OrganisationUser::role_admin_level(q.get_first_role(), user.id, conn) - .is_at_least_director() - .or(c.published) - .check() - .map_err(|_| JsonErr(QuestionError::InsufficientPermissions, Status::Forbidden))?; - Ok(q) - }) - .await - .map(|q| Json(QuestionResponse::from(q))) -} - -#[put("/", data = "")] -pub async fn edit_question( - db: Database, - question_id: i32, - update_question: Json, - user: User, -) -> Result<(), JsonErr> { - db.run(move |conn| { - let question = Question::get_from_id(&conn, question_id) - .ok_or(JsonErr(QuestionError::QuestionNotFound, Status::NotFound))?; - let role = Role::get_from_id(conn, question.get_first_role()) - .ok_or(JsonErr(QuestionError::QuestionNotFound, Status::NotFound))?; - - OrganisationUser::role_admin_level(role.id, user.id, &conn) - .is_at_least_director() - .check() - .or_else(|_| { - Err(JsonErr( - QuestionError::InsufficientPermissions, - Status::Forbidden, - )) - })?; - - Question::update(&conn, question_id, update_question.into_inner()).ok_or(JsonErr( - QuestionError::UpdateFailed, - Status::InternalServerError, - )) - }) - .await -} - -#[delete("/")] -pub async fn delete_question( - db: Database, - question_id: i32, - user: User, -) -> Result<(), JsonErr> { - db.run(move |conn| { - let question = Question::get_from_id(&conn, question_id) - .ok_or(JsonErr(QuestionError::QuestionNotFound, Status::NotFound))?; - let role = Role::get_from_id(conn, question.get_first_role()) - .ok_or(JsonErr(QuestionError::QuestionNotFound, Status::NotFound))?; - - OrganisationUser::role_admin_level(role.id, user.id, &conn) - .is_at_least_director() - .check() - .or_else(|_| { - Err(JsonErr( - QuestionError::InsufficientPermissions, - Status::Forbidden, - )) - })?; - - if Question::delete(&conn, question_id) { - Ok(()) - } else { - Err(JsonErr( - QuestionError::UpdateFailed, - Status::InternalServerError, - )) - } - }) - .await -} diff --git a/backend/server/src/role.rs b/backend/server/src/role.rs deleted file mode 100644 index 51426c84b..000000000 --- a/backend/server/src/role.rs +++ /dev/null @@ -1,228 +0,0 @@ -use crate::database::{ - models::{ - Application, Campaign, GetQuestionsResponse, OrganisationUser, Question, Role, RoleUpdate, - User, - }, - schema::ApplicationStatus, - Database, -}; -use chrono::NaiveDateTime; -use diesel::PgConnection; -use rocket::{ - delete, get, post, put, - serde::{json::Json, Serialize}, -}; - -#[derive(Serialize)] -pub enum RoleError { - RoleUpdateFailure, - RoleNotFound, - CampaignNotFound, - Unauthorized, - RoleAlreadyExists, -} - -#[derive(Serialize)] -pub struct RoleResponse { - name: String, - description: Option, - min_available: i32, - max_available: i32, -} - -impl From for RoleResponse { - fn from(role: Role) -> Self { - RoleResponse { - name: role.name, - description: role.description, - min_available: role.min_available, - max_available: role.max_available, - } - } -} - -#[get("/")] -pub async fn get_role( - role_id: i32, - _user: User, - db: Database, -) -> Result, Json> { - let res = db.run(move |conn| Role::get_from_id(&conn, role_id)).await; - - match res { - Some(role) => Ok(Json(RoleResponse::from(role))), - None => Err(Json(RoleError::RoleNotFound)), - } -} - -#[put("/", data = "")] -pub async fn update_role( - role_id: i32, - role_update: Json, - user: User, - db: Database, -) -> Result, Json> { - db.run(move |conn| { - OrganisationUser::role_admin_level(role_id, user.id, &conn) - .is_at_least_director() - .check() - .or_else(|_| Err(Json(RoleError::Unauthorized)))?; - - let role = Role::update(conn, role_id, &role_update) - .ok_or_else(|| Json(RoleError::RoleUpdateFailure))?; - - Ok(Json(role.into())) - }) - .await -} - -#[delete("/")] -pub async fn delete_role(role_id: i32, user: User, db: Database) -> Result<(), Json> { - db.run(move |conn| { - OrganisationUser::role_admin_level(role_id, user.id, &conn) - .is_at_least_director() - .check() - .or_else(|_| Err(Json(RoleError::Unauthorized)))?; - - Role::delete_deep(conn, role_id).ok_or_else(|| Json(RoleError::RoleUpdateFailure))?; - - Ok(()) - }) - .await -} - -#[post("/", data = "")] -pub async fn new_role( - role: Json, - user: User, - db: Database, -) -> Result<(), Json> { - db.run(move |conn| { - OrganisationUser::campaign_admin_level(role.campaign_id, user.id, &conn) - .is_at_least_director() - .check() - .or_else(|_| Err(Json(RoleError::Unauthorized)))?; - - RoleUpdate::insert(&role, &conn).ok_or_else(|| Json(RoleError::RoleAlreadyExists))?; - - Ok(()) - }) - .await -} - -#[derive(Serialize)] -pub enum QuestionsError { - RoleNotFound, - CampaignNotFound, - Unauthorized, - UserNotFound, -} - -#[get("//questions")] -pub async fn get_questions( - role_id: i32, - user: User, - db: Database, -) -> Result, Json> { - // First check that the role is valid and the user should be able to access the ids. - // We can't use the helper function below since behaviour depends on the draft - // status of the campaign. - - db.run(move |conn| { - let role = Role::get_from_id(conn, role_id).ok_or(Json(QuestionsError::RoleNotFound))?; - let campaign = Campaign::get_from_id(conn, role.campaign_id) - .ok_or(Json(QuestionsError::CampaignNotFound))?; - - // Prevent people from viewing while it's in draft mode, - // unless they have adequate permissions - OrganisationUser::campaign_admin_level(campaign.id, user.id, &conn) - .is_at_least_director() - .or(campaign.published) - .check() - .map_err(|_| Json(QuestionsError::Unauthorized))?; - Ok(Json(GetQuestionsResponse { - questions: Question::get_all_from_role_id(conn, role_id) - .into_iter() - .map(|x| x.into()) - .collect(), - })) - }) - .await -} - -#[derive(Serialize)] -pub struct ApplicationResponse { - pub id: i32, - pub user_id: i32, - pub user_email: String, - pub user_zid: String, - pub user_display_name: String, - pub user_degree_name: String, - pub user_degree_starting_year: i32, - pub role_id: i32, - pub status: ApplicationStatus, - pub private_status: ApplicationStatus, - pub created_at: NaiveDateTime, - pub updated_at: NaiveDateTime, -} - -impl ApplicationResponse { - pub fn from_application(app: Application, conn: &PgConnection) -> Option { - let user = User::get_from_id(conn, app.user_id)?; - - Some(ApplicationResponse { - id: app.id, - user_id: app.user_id, - user_display_name: user.display_name, - user_email: user.email, - user_degree_name: user.degree_name, - user_degree_starting_year: user.degree_starting_year, - user_zid: user.zid, - role_id: app.role_id, - status: app.status, - private_status: app.private_status, - created_at: app.created_at, - updated_at: app.updated_at, - }) - } -} - -#[derive(Serialize)] -pub struct GetApplicationsResponse { - pub applications: Vec, -} - -#[get("//applications")] -pub async fn get_applications( - role_id: i32, - user: User, - db: Database, -) -> Result, Json> { - // First check that the role is valid and the user should be able to access the ids. - // We can't use the helper function below since behaviour depends on the draft - // status of the campaign. - - db.run(move |conn| { - // NOTE: admin_level doesn't give good error info when eg. role is not found - // (just says unauthorized) - OrganisationUser::role_admin_level(role_id, user.id, conn) - .is_at_least_director() - .check() - .map_err(|_| QuestionsError::Unauthorized)?; - - let apps = Application::get_all_from_role_id(conn, role_id); - let mut res_vec = Vec::with_capacity(apps.len()); - - for app in apps { - res_vec.push( - ApplicationResponse::from_application(app, conn) - .ok_or(Json(QuestionsError::UserNotFound))?, - ); - } - - Ok(Json(GetApplicationsResponse { - applications: res_vec, - })) - }) - .await -} diff --git a/backend/server/src/schema.jpg b/backend/server/src/schema.jpg deleted file mode 100644 index 6bf1d5aad39e6292ade7d88b20f79a0f61a9c8e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 315172 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

YFE+H)lKZ=wiqDgr}8Qv37^^hdt361EpEj^9kI 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%0Ai>%^ILMX0P|xn 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

jx7_U`)+xS<1LEdlSdLuAa!(p@Wa(Rw+T+_Gu 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 GZvp^UxTG-v diff --git a/backend/server/src/schema.png b/backend/server/src/schema.png deleted file mode 100644 index d075a240acd3991b0c131d06a1ea065298356bbd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 598648 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

;_9RZL-f7DQiH)&C`0iCBE9J%+etRu`?O%a; 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

*n|wmGZ#r2w}RnREYjXj0^)**D)6vnR8d#3 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 z%0D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�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

0VtA+qm*8q-VOf6xdwbPx-vn7CkQU;% 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%0Dswn4OZ4G&{69Tc=tj6 zwOQ}68T|@ULlH*lGlb$0xbc%@Cl40=ptYANZ@?;VVw-Oql|qK=j~iHvD{Ks+VHwUB zcI_bvzWLRYl4LQ`Cmla$XX`Ya6Krg%M~Co*G3xR2ibZAf88%V;cnpH?2E(a}cH~M1 z)mf+2JiEP`FF6o7FnY&tU#Rlx=+Y zAyFQw6YpS!&k`mD;>&>#x;VxMDC>><0(pBp3AUZD6s_oAL=g=WlVhmugKy$EQB{ zrYORBT%Q8D3+WJQw?%Y|wFPU2I94;jzn3qXM;2gkiI-D;oj+*$7DW>g=RljcRICgH zHy0tJwI0ZLyhcVi07{8?e_2#u?krJM{Cy{CitN-_yi5Gw?Od=Tzkpwf(13+DSPj*0 z7^sv9L={vzDlA6d}J3z>uLP>%{P+D;u!1EDTN;a36;(3r#E7j*($mAfU za`DJN0R8Su``#4;Wn|?~GPsYTng3}t>9S>G{!TeeT z>KnJ9l|mG$J0oTsE}O_^wua{%)t8d^>Q)4r$7SLa0b%4Uu9uV}KIs=m1-zgk3KhNi zx=MVzEL2jg?QYv`;@D_@?MtQ3+;sZofU9qK3!yVoYIkK!2}#q45l+08*4}kW294ER zh9PtioF%qbqFUuAl0>%qe2scGryzSF1w5}k{?VSY5si@IP9bBIe1}z8 zu)e$I2p(}3f|jASZTQ{O8&FV=iX#}NKFqp+VDm>DUGKF&!TJ+>P?87{{9=7(Ksd}` z1;Y5PZ+C3lH%ml59ReC-ZAJ39fgqPXHIGy7CqZTPIQ~@yTj4JX8+bSa zteLFiZOo>)m8`f*7&i?w5!-&KKWrokBAJbET+V|io-x13FXMxT(Q1SbfjlP{DMMFx zH3mGAiqBL5*%MRllf-Hf10koAPi$UiL?PUkuxw}I961m(fd-~AU2~g~iP-`q$>@&BCUg&k? z3p!w2LA3%{<2gA<)aEG8j}R$>0ygHYgY;KF`CtF?cPmp6=vUb8%N@T@06M#I|MKt@{?x|yA$~)MHJ2<55^mGZ{To% z1ePsn{myIm<4c4G*XJ`fC_n5 zQw? zI_}ns91v%{FdE9YrcU^PxcS3f`%$ZcBUYKkM~R19GuxeSN}U93#44@h>iUaiXAEs6k^kapr60UD{L=M;P8R7W8a9&(aaDY3kN1({0ddv5>$B z3MN~P>d}@^2VNlX@L@6K!8S&Dg%I5Z2cJ#BqGtYaVok4GPyOogalHTJ^X?g!n&;eL z6=jny(LzBp3n+XQ3VjM)g+_#3+7_(wQjs5`q53|9DM$1MJ{ty^oCQ zP}2f`y)1rBe9a)6qpe%%dOd>og^AH+z=F=z$_znJC9f4^u_^p4+}0K~EIE#LBCr#h z(|2u_6UyMyj#`!T>+)@K_;#J6a1|Y6xY^UH@S#j;kuEh~mg1(ARN}V<-&WdR*}-e4 zc@Cmmf98@StXhhUN?t{)Nq0yj z%je=uPhw=hJHmyLn$(y$cGHZTdG&b*Cmy^?J|T_b|5lJtJ)VOj6 z6;N>&gR(N`tS=!~IdVE++?hMr{0)!smo6lpx0t_oYmpw?yGJ+FZ+_?A+{R}eaWNP1 zmLgq>QY1pm%eHCMJ)n}I+qY0e!kS5$$vwB9^VQbp-LFZoYoFqL(eur9_2HQNS+S

R390esuKt6qiRVU>nWOVIK>o| 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 diff --git a/backend/server/src/src/database/schema.rs b/backend/server/src/src/database/schema.rs deleted file mode 100644 index f138f6d23..000000000 --- a/backend/server/src/src/database/schema.rs +++ /dev/null @@ -1,174 +0,0 @@ -// @generated automatically by Diesel CLI. - -pub mod sql_types { - #[derive(diesel::sql_types::SqlType)] - #[diesel(postgres_type(name = "admin_level"))] - pub struct AdminLevel; - - #[derive(diesel::sql_types::SqlType)] - #[diesel(postgres_type(name = "application_status"))] - pub struct ApplicationStatus; - - #[derive(diesel::sql_types::SqlType)] - #[diesel(postgres_type(name = "user_gender"))] - pub struct UserGender; -} - -diesel::table! { - answers (id) { - id -> Int4, - application_id -> Int4, - question_id -> Int4, - description -> Text, - created_at -> Timestamp, - updated_at -> Timestamp, - } -} - -diesel::table! { - use diesel::sql_types::*; - use super::sql_types::ApplicationStatus; - - applications (id) { - id -> Int4, - user_id -> Int4, - role_id -> Int4, - status -> ApplicationStatus, - created_at -> Timestamp, - updated_at -> Timestamp, - private_status -> Nullable, - } -} - -diesel::table! { - campaigns (id) { - id -> Int4, - organisation_id -> Int4, - name -> Text, - cover_image -> Nullable, - description -> Text, - starts_at -> Timestamp, - ends_at -> Timestamp, - published -> Bool, - created_at -> Timestamp, - updated_at -> Timestamp, - } -} - -diesel::table! { - comments (id) { - id -> Int4, - application_id -> Int4, - commenter_user_id -> Int4, - description -> Text, - created_at -> Timestamp, - updated_at -> Timestamp, - } -} - -diesel::table! { - use diesel::sql_types::*; - use super::sql_types::AdminLevel; - - organisation_users (id) { - id -> Int4, - user_id -> Int4, - organisation_id -> Int4, - admin_level -> AdminLevel, - created_at -> Timestamp, - updated_at -> Timestamp, - } -} - -diesel::table! { - organisations (id) { - id -> Int4, - name -> Text, - logo -> Nullable, - created_at -> Timestamp, - updated_at -> Timestamp, - } -} - -diesel::table! { - questions (id) { - id -> Int4, - role_ids -> Array>, - title -> Text, - description -> Nullable, - max_bytes -> Int4, - required -> Bool, - created_at -> Timestamp, - updated_at -> Timestamp, - } -} - -diesel::table! { - ratings (id) { - id -> Int4, - application_id -> Int4, - rater_user_id -> Int4, - rating -> Int4, - created_at -> Timestamp, - updated_at -> Timestamp, - } -} - -diesel::table! { - roles (id) { - id -> Int4, - campaign_id -> Int4, - name -> Text, - description -> Nullable, - min_available -> Int4, - max_available -> Int4, - finalised -> Bool, - created_at -> Timestamp, - updated_at -> Timestamp, - } -} - -diesel::table! { - use diesel::sql_types::*; - use super::sql_types::UserGender; - - users (id) { - id -> Int4, - email -> Text, - zid -> Text, - display_name -> Text, - degree_name -> Text, - degree_starting_year -> Int4, - superuser -> Bool, - created_at -> Timestamp, - updated_at -> Timestamp, - gender -> UserGender, - pronouns -> Text, - } -} - -diesel::joinable!(answers -> applications (application_id)); -diesel::joinable!(answers -> questions (question_id)); -diesel::joinable!(applications -> roles (role_id)); -diesel::joinable!(applications -> users (user_id)); -diesel::joinable!(campaigns -> organisations (organisation_id)); -diesel::joinable!(comments -> applications (application_id)); -diesel::joinable!(comments -> users (commenter_user_id)); -diesel::joinable!(organisation_users -> organisations (organisation_id)); -diesel::joinable!(organisation_users -> users (user_id)); -diesel::joinable!(ratings -> applications (application_id)); -diesel::joinable!(ratings -> users (rater_user_id)); -diesel::joinable!(roles -> campaigns (campaign_id)); - -diesel::allow_tables_to_appear_in_same_query!( - answers, - applications, - campaigns, - comments, - organisation_users, - organisations, - questions, - ratings, - roles, - users, -); diff --git a/backend/server/src/state/mod.rs b/backend/server/src/state/mod.rs deleted file mode 100644 index 8a83510af..000000000 --- a/backend/server/src/state/mod.rs +++ /dev/null @@ -1,66 +0,0 @@ -use dotenv; -use jsonwebtoken::{DecodingKey, EncodingKey}; -use once_cell::sync::OnceCell; -use reqwest::Client; -use serde_json::Value; - -const GOOGLE_OPENID_DISCOVERY_URL: &str = - "https://accounts.google.com/.well-known/openid-configuration"; -const GOOGLE_OPENID_USERINFO_KEY: &str = "userinfo_endpoint"; - -pub struct GlobalStringRef {} - -static INSTANCE: OnceCell = OnceCell::new(); - -impl GlobalStringRef { - pub fn global() -> &'static String { - INSTANCE.get().expect("String not initialized") - } -} - -pub struct ApiState { - pub reqwest_client: Client, - pub jwt_encoding_key: EncodingKey, - pub jwt_decoding_key: DecodingKey, - pub userinfo_endpoint: String, -} - -pub async fn api_state() -> ApiState { - let reqwest_client = Client::new(); - - let jwt_secret = dotenv::var("JWT_SECRET").expect("JWT_SECRET should be in env"); - - INSTANCE - .set(jwt_secret) - .expect("Failed to initialize jwt_secret"); - - let discovery = reqwest::get(GOOGLE_OPENID_DISCOVERY_URL) - .await - .expect(&format!( - "Failed to fetch openid discovery from {:?}", - GOOGLE_OPENID_DISCOVERY_URL - )) - .json::>() - .await - .expect("Failed to parse openid discovery as a JSON Object"); - - let userinfo_endpoint = match discovery.get(GOOGLE_OPENID_USERINFO_KEY).expect(&format!( - "Openid discovery does not contain a {:?} key", - GOOGLE_OPENID_USERINFO_KEY - )) { - Value::String(url) => url.to_string(), - other => panic!( - "Openid discovery {:?} key has incorrect type {:?}", - GOOGLE_OPENID_USERINFO_KEY, other - ), - }; - - let api_state = ApiState { - reqwest_client, - jwt_encoding_key: EncodingKey::from_secret(GlobalStringRef::global().as_bytes()), - jwt_decoding_key: DecodingKey::from_secret(GlobalStringRef::global().as_bytes()), - userinfo_endpoint, - }; - - api_state -} diff --git a/backend/server/src/static_resources.rs b/backend/server/src/static_resources.rs deleted file mode 100644 index a1df8a5b8..000000000 --- a/backend/server/src/static_resources.rs +++ /dev/null @@ -1,26 +0,0 @@ -use std::path::{Path, PathBuf}; - -use rocket::{ - fs::NamedFile, - get, - response::{self, Responder}, - Request, Response, -}; - -pub struct CachedFile(NamedFile); - -impl<'r> Responder<'r, 'r> for CachedFile { - fn respond_to(self, req: &Request) -> response::Result<'r> { - Response::build_from(self.0.respond_to(req)?) - .raw_header("Cache-control", "max-age=86400") // 24h (24*60*60) - .ok() - } -} - -#[get("/images/")] -pub async fn files(file: PathBuf) -> Option { - NamedFile::open(Path::new("images/").join(file)) - .await - .ok() - .map(|nf| CachedFile(nf)) -} diff --git a/backend/server/src/user.rs b/backend/server/src/user.rs deleted file mode 100644 index 21902bfda..000000000 --- a/backend/server/src/user.rs +++ /dev/null @@ -1,88 +0,0 @@ -use crate::database::{ - models::{Application, Campaign, OrganisationUser, User}, - Database, -}; -use crate::error::JsonErr; -use diesel::PgConnection; -use rocket::{ - get, - http::Status, - serde::{json::Json, Serialize}, -}; - -#[derive(Serialize)] -pub struct UserResponse { - email: String, - zid: String, - display_name: String, - degree_name: String, - degree_starting_year: i32, -} - -#[derive(Serialize)] -pub enum UserError { - UserNotFound, - CampaignNotFound, - PermissionDenied, -} - -fn user_is_boss(boss_user: &User, user: &User, conn: &PgConnection) -> bool { - if boss_user.id == user.id { - return true; - } - - let apps = Application::get_all_from_user_id(conn, user.id); - for app in &apps { - let boss_mode = OrganisationUser::role_admin_level(app.role_id, boss_user.id, conn) - .is_at_least_director() - .check() - .is_ok(); - if boss_mode { - return true; - } - } - false -} - -#[get("/")] -pub async fn get(user: User) -> Json { - Json(UserResponse { - email: user.email, - zid: user.zid, - display_name: user.display_name, - degree_name: user.degree_name, - degree_starting_year: user.degree_starting_year, - }) -} - -#[get("/")] -pub async fn get_user( - user_id: i32, - user: User, - db: Database, -) -> Result, JsonErr> { - db.run(move |conn| { - let res = User::get_from_id(&conn, user_id) - .ok_or(JsonErr(UserError::UserNotFound, Status::NotFound))?; - - if user_is_boss(&user, &res, conn) { - Ok(Json(UserResponse { - email: user.email, - zid: user.zid, - display_name: user.display_name, - degree_name: user.degree_name, - degree_starting_year: user.degree_starting_year, - })) - } else { - Err(JsonErr(UserError::PermissionDenied, Status::Forbidden)) - } - }) - .await -} - -#[get("/campaigns")] -pub async fn get_user_campaigns(user: User, db: Database) -> Json> { - let campaigns = db.run(move |conn| user.get_all_campaigns(conn)).await; - - Json(campaigns) -} From d6b5fa4fc2fb605895a47114e33d0ac2d35bf228 Mon Sep 17 00:00:00 2001 From: Kavika <50282464+KavikaPalletenne@users.noreply.github.com> Date: Thu, 5 Oct 2023 12:39:27 +1100 Subject: [PATCH 02/56] feat(backend): add README for new backend structure --- backend/README.md | 69 ++++++++++++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 25 deletions(-) diff --git a/backend/README.md b/backend/README.md index 429197093..d4015bd49 100644 --- a/backend/README.md +++ b/backend/README.md @@ -1,25 +1,44 @@ -# Setup guide - -* Install the latest (stable) Rust toolchain with [rustup](https://rustup.rs/) -* Install postgres with associated dev tools, eg. `sudo apt install postgresql-all` (something like `brew install postgresql` for osx) -* Download and save the backend `.env` file from vault to the root of the backend folder. -* Setup postgres accordingly - * Make sure the user is named `postgres` and the password is the same as the one in vault `.env` file - * the password is in the `DATABSE_URL` field, which will look very similar to `postgres://postgres:@localhost/chaos` -* Install diesel-cli with `cargo install diesel_cli --no-default-features --features postgres` -* Run `diesel setup && diesel migration run` - * If you get a server connection error, check out [this stackoverflow thread](https://stackoverflow.com/questions/32439167/psql-could-not-connect-to-server-connection-refused-error-when-connecting-to) - * this might delete code in the backend, make sure to restore any deletions. -* Run the server with `cargo run --bin server` - * If you want to run the server and get it to restart upon changes, you can install `cargo watch` with `cargo install cargo-watch` - * Then, run `cargo watch -x 'run --bin server'` instead - * It will watch files and continually re-compile upon changes -* If there are errrors, ask on discord. - - -# Scripts - -Scripts should be run from the `chaos/backend` directory: - * `scripts/become_super_user`- will prompt for the email address to turn into a GLOBAL super user - * `scripts/seed.sh` - will wipe your database and add some dummy data - * If you are getting a `bad variable nameread answer` error, ensure the file has LF-style newlines +# CHAOS Backend + +CHAOS' backend is implemented in Rust and for data persistence, we use PostgreSQL. + +## Code Structure +### Service +The service module contains all functions that conduct business logic, and also interact with the database. This +separation from the request handling makes it easy to swap out any new form of requests, but reuse the same business +logic. + +### Handler +The handler module takes care of request handling. It implements the framework or library we are using, invokes the +service functions and responds via HTTP with their return values. + +### Middleware +The middleware module contains middlewares, functions that run before or after the function handlers. A common use case +is authorization, where middleware is used to find the userId from the user's token. + +### Models +Models are Rust structs that represent the data. There must be a struct for each table in the database, as well as a +struct to describe the fully joined data. E.g. A campaign struct with a array of questions, even though questions are +stored as rows in a separate table. These models are used by the service functions when interacting with the database, +and also when conducting business logic. + +#### Request Path +Request -> Middleware (optional) -> Handler -> Service -> Middleware (Optional) -> Response + + +## Tech Stack +### Web Server +[Axum](https://github.com/tokio-rs/axum) + +### Persistence +- [SQLx](https://github.com/launchbadge/sqlx) - Queries +- [Prisma](https://www.prisma.io/) - Migrations and Schema + +### AuthN +- OAuth 2 (Google) + +### AuthZ +- JWT + +### Storage +- Local file system \ No newline at end of file From 262445ee6d99ff8ffbcac46a94b6b5bbc64cddcc Mon Sep 17 00:00:00 2001 From: Kavika Date: Sat, 7 Oct 2023 14:31:34 +1100 Subject: [PATCH 03/56] feat(backend): Update README.md to include postgres in techstack --- backend/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/backend/README.md b/backend/README.md index d4015bd49..4135e0b4d 100644 --- a/backend/README.md +++ b/backend/README.md @@ -28,11 +28,12 @@ Request -> Middleware (optional) -> Handler -> Service -> Middleware (Optional) ## Tech Stack ### Web Server -[Axum](https://github.com/tokio-rs/axum) +- [Axum](https://github.com/tokio-rs/axum) ### Persistence - [SQLx](https://github.com/launchbadge/sqlx) - Queries - [Prisma](https://www.prisma.io/) - Migrations and Schema +- PostgreSQL ### AuthN - OAuth 2 (Google) @@ -41,4 +42,4 @@ Request -> Middleware (optional) -> Handler -> Service -> Middleware (Optional) - JWT ### Storage -- Local file system \ No newline at end of file +- Local file system From 0f7c413ae8054427121c60f543b83475179bdf10 Mon Sep 17 00:00:00 2001 From: Kavika <50282464+KavikaPalletenne@users.noreply.github.com> Date: Wed, 25 Oct 2023 14:56:03 +1100 Subject: [PATCH 04/56] feat(backend): add OAuth2 token and email fetching for Google callback --- backend/server/Cargo.toml | 43 ++++++++------------------- backend/server/src/handler/auth.rs | 44 ++++++++++++++++++++++++++++ backend/server/src/handler/mod.rs | 1 + backend/server/src/main.rs | 15 ++++++++++ backend/server/src/models/app.rs | 7 +++++ backend/server/src/models/auth.rs | 11 +++++++ backend/server/src/models/mod.rs | 2 ++ backend/server/src/service/auth.rs | 14 +++++++++ backend/server/src/service/mod.rs | 2 ++ backend/server/src/service/oauth2.rs | 30 +++++++++++++++++++ 10 files changed, 138 insertions(+), 31 deletions(-) create mode 100644 backend/server/src/handler/auth.rs create mode 100644 backend/server/src/handler/mod.rs create mode 100644 backend/server/src/main.rs create mode 100644 backend/server/src/models/app.rs create mode 100644 backend/server/src/models/auth.rs create mode 100644 backend/server/src/models/mod.rs create mode 100644 backend/server/src/service/auth.rs create mode 100644 backend/server/src/service/mod.rs create mode 100644 backend/server/src/service/oauth2.rs diff --git a/backend/server/Cargo.toml b/backend/server/Cargo.toml index a0e60570b..b1cfda7e3 100644 --- a/backend/server/Cargo.toml +++ b/backend/server/Cargo.toml @@ -3,38 +3,19 @@ name = "server" version = "0.1.0" edition = "2021" - -[lib] -name = "backend" -path = "src/lib.rs" - -[[bin]] -name = "server" -path = "src/bin.rs" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -rocket = { version = "0.5.0-rc.2", features = ["json"] } -rocket_sync_db_pools = { version = "0.1.0-rc.2", features = ["diesel_postgres_pool"] } -# pull rocket_cors from git master until crates.io artifact builds on stable -rocket_cors = { git = "https://github.com/lawliet89/rocket_cors", branch = "master" } -diesel = { version = "1.4.8", features = ["postgres", "r2d2", "chrono"] } -diesel-derive-enum = { version = "1", features = ["postgres"] } -dotenv = "0.15.0" -dotenv_codegen = "0.15.0" -reqwest = { version = "0.11.13", features = ["json"] } -jsonwebtoken = "8.3.0" -serde = {version = "1.0", features = ["derive"] } -serde_json = "1.0.89" -chrono = { version = "0.4", features = ["serde"] } -itertools = "0.10.5" -once_cell = "1.18.0" -diesel_migrations = "1.4.0" -figment = { version = "0.10", features = ["env", "toml", "json"] } -image = "0.24.4" -strum = { version = "0.24", features = ["derive"] } -webp = "0.2" +# Primary crates +tokio = { version = "1.32.0", features = ["macros", "rt-multi-thread"] } +axum = { version = "0.6.20", features = ["macros"] } +sqlx = { version = "0.7.1", features = ["runtime-tokio-rustls", "postgres", "time", "uuid"] } -[dependencies.uuid] -version = "1.3.3" -features = ["v4", "fast-rng", "macro-diagnostics"] +# Important secondary crates +anyhow = "1.0.75" +serde = { version = "1.0.188", features = ["derive"] } +reqwest = "0.11.20" +serde_json = "1.0.105" +chrono = { version = "0.4.26", features = ["serde"] } +oauth2 = "4.4.1" +log = "0.4.20" diff --git a/backend/server/src/handler/auth.rs b/backend/server/src/handler/auth.rs new file mode 100644 index 000000000..5ca7f67e2 --- /dev/null +++ b/backend/server/src/handler/auth.rs @@ -0,0 +1,44 @@ +use axum::Extension; +use axum::extract::{Query, State}; +use axum::http::StatusCode; +use axum::response::IntoResponse; +use log::error; +use oauth2::{AuthorizationCode, TokenResponse}; +use oauth2::basic::BasicClient; +use oauth2::reqwest::async_http_client; +use crate::models::app::AppState; +use crate::models::auth::{AuthRequest, UserProfile}; +use crate::service::auth::create_or_get_user_id; + +/// This function handles the passing in of the Google OAuth code. After allowing our app the +/// requested permissions, the user is redirected to this url on our server, where we use the +/// code to get the user's email address from Google's OpenID Connect API. +pub async fn google_callback( + State(state): State, + Query(query): Query, + Extension(oauth_client): Extension +) -> Result { + let token = match oauth_client + .exchange_code(AuthorizationCode::new(query.code)) + .request_async(async_http_client) + .await { + Ok(res) => res, + Err(e) => { + error!("An error occured while exchanging Google OAuth code"); + return Err((StatusCode::INTERNAL_SERVER_ERROR, e.to_string())) + } + }; + + let profile = match state.ctx.get("https://openidconnect.googleapis.com/v1/userinfo") + .bearer_auth(token.access_token().secret().to_owned()) + .send().await { + Ok(res) => res, + Err(e) => return Err((StatusCode::INTERNAL_SERVER_ERROR, e.to_string())) + }; + + let profile = profile.json::().await.unwrap(); + + let user_id = create_or_get_user_id(profile.email, state.db).await?; + + // TODO: Create a JWT from this user_id and return to the user. +} \ No newline at end of file diff --git a/backend/server/src/handler/mod.rs b/backend/server/src/handler/mod.rs new file mode 100644 index 000000000..5696e21f9 --- /dev/null +++ b/backend/server/src/handler/mod.rs @@ -0,0 +1 @@ +pub mod auth; \ No newline at end of file diff --git a/backend/server/src/main.rs b/backend/server/src/main.rs new file mode 100644 index 000000000..2eef9c5f5 --- /dev/null +++ b/backend/server/src/main.rs @@ -0,0 +1,15 @@ +use axum::{routing::get, Router}; + +mod service; +mod models; +mod handler; + +#[tokio::main] +async fn main() { + let app = Router::new().route("/", get(|| async { "Hello, World!" })); + + axum::Server::bind(&"0.0.0.0:3000".parse().unwrap()) + .serve(app.into_make_service()) + .await + .unwrap(); +} diff --git a/backend/server/src/models/app.rs b/backend/server/src/models/app.rs new file mode 100644 index 000000000..613683f1b --- /dev/null +++ b/backend/server/src/models/app.rs @@ -0,0 +1,7 @@ +use sqlx::{Pool, Postgres}; +use reqwest::Client as ReqwestClient; + +pub struct AppState { + pub db: Pool, + pub ctx: ReqwestClient +} \ No newline at end of file diff --git a/backend/server/src/models/auth.rs b/backend/server/src/models/auth.rs new file mode 100644 index 000000000..fc35a14e3 --- /dev/null +++ b/backend/server/src/models/auth.rs @@ -0,0 +1,11 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Deserialize, Serialize)] +pub struct AuthRequest { + pub code: String +} + +#[derive(Deserialize, Serialize)] +pub struct UserProfile { + pub email: String +} \ No newline at end of file diff --git a/backend/server/src/models/mod.rs b/backend/server/src/models/mod.rs new file mode 100644 index 000000000..b1c8d1e75 --- /dev/null +++ b/backend/server/src/models/mod.rs @@ -0,0 +1,2 @@ +pub mod auth; +pub mod app; \ No newline at end of file diff --git a/backend/server/src/service/auth.rs b/backend/server/src/service/auth.rs new file mode 100644 index 000000000..16333e6fb --- /dev/null +++ b/backend/server/src/service/auth.rs @@ -0,0 +1,14 @@ +use anyhow::Result; +use sqlx::{Pool, Postgres}; + +/// Checks if a user exists in DB based on given email address. If so, their user_id is returned. +/// Otherwise, a new user is created in the DB, and the new id is returned. +/// This function is used in OAuth flows to login/signup users when they click the +/// "Sign in with ___" buttons. The returned user_id will be used to generate a JWT to be +/// used as a token for the user's browser. +pub async fn create_or_get_user_id(email: String, pool: Pool) -> Result { + // TODO: See if user (by email) exists in the database and return their id. If not, insert them, and return the new id. + + let user_id = 1; + return Ok(user_id); +} \ No newline at end of file diff --git a/backend/server/src/service/mod.rs b/backend/server/src/service/mod.rs new file mode 100644 index 000000000..95b107626 --- /dev/null +++ b/backend/server/src/service/mod.rs @@ -0,0 +1,2 @@ +pub mod auth; +pub mod oauth2; diff --git a/backend/server/src/service/oauth2.rs b/backend/server/src/service/oauth2.rs new file mode 100644 index 000000000..92e60c420 --- /dev/null +++ b/backend/server/src/service/oauth2.rs @@ -0,0 +1,30 @@ +use oauth2::{ + AuthUrl, + ClientId, + ClientSecret, + RedirectUrl, + TokenUrl +}; +use oauth2::basic::BasicClient; +use std::env; + +/// Returns a oauth2::BasicClient, setup with settings for CHAOS Google OAuth. +/// Client follows OAuth2 Standard (https://oauth.net/2/) to get user's email +/// using OpenID Connect (https://openid.net/developers/how-connect-works/). +pub fn build_oauth_client(client_id: String, client_secret: String) -> BasicClient { + let hostname = env::var("CHAOS_HOSTNAME").expect("Could not read CHAOS hostname"); + + let redirect_url = format!("{}/api/auth/google_callback", hostname); + + let auth_url = AuthUrl::new("https://accounts.google.com/o/oauth2/v2/auth".to_string()) + .expect("Invalid authorization endpoint URL"); + let token_url = TokenUrl::new("https://www.googleapis.com/oauth2/v3/token".to_string()) + .expect("Invalid token endpoint URL"); + + BasicClient::new( + ClientId::new(client_id), + Some(ClientSecret::new(client_secret)), + auth_url, + Some(token_url), + ).set_redirect_uri(RedirectUrl::new(redirect_url).unwrap()) +} \ No newline at end of file From fe3d0e23b506450e1dad56efb40101dfdd4b2d5a Mon Sep 17 00:00:00 2001 From: William Zhang Date: Wed, 25 Oct 2023 17:16:09 +1100 Subject: [PATCH 05/56] feat(backend): add prisma-cli and design schema --- backend/.gitignore | 3 + backend/prisma-cli/Cargo.toml | 14 +++ backend/prisma-cli/prisma/schema.prisma | 156 ++++++++++++++++++++++++ backend/prisma-cli/src/main.rs | 3 + 4 files changed, 176 insertions(+) create mode 100644 backend/.gitignore create mode 100644 backend/prisma-cli/Cargo.toml create mode 100644 backend/prisma-cli/prisma/schema.prisma create mode 100644 backend/prisma-cli/src/main.rs diff --git a/backend/.gitignore b/backend/.gitignore new file mode 100644 index 000000000..c5def5af4 --- /dev/null +++ b/backend/.gitignore @@ -0,0 +1,3 @@ +.env +target +Cargo.lock diff --git a/backend/prisma-cli/Cargo.toml b/backend/prisma-cli/Cargo.toml new file mode 100644 index 000000000..585fc7090 --- /dev/null +++ b/backend/prisma-cli/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "prisma-cli" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +prisma-client-rust-cli = { git = "https://github.com/Brendonovich/prisma-client-rust", tag = "0.6.10", features = [ + "postgresql", +] } + +[alias] +prisma = "run --bin prisma-cli --" diff --git a/backend/prisma-cli/prisma/schema.prisma b/backend/prisma-cli/prisma/schema.prisma new file mode 100644 index 000000000..b6368e938 --- /dev/null +++ b/backend/prisma-cli/prisma/schema.prisma @@ -0,0 +1,156 @@ +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") +} + +model User { + id BigInt @id + email String @unique + zid String? + name String + degree_name String? + degree_starting_year Int? + created_at DateTime @default(now()) + updated_at DateTime + role UserRole @default(USER) + applications Application[] + OrganisationAdmins OrganisationAdmins[] + Ratings Ratings[] +} + +enum UserRole { + USER + SUPERUSER +} + +model Organisation { + id BigInt @id + name String + logo String? + created_at DateTime @default(now()) + updated_at DateTime @default(now()) + campaigns Campaign[] + OrganisationAdmins OrganisationAdmins[] +} + +model OrganisationAdmins { + Organisation Organisation @relation(fields: [organisation_id], references: [id]) + organisation_id BigInt + User User @relation(fields: [user_id], references: [id]) + user_id BigInt + + @@id([organisation_id, user_id]) +} + +model Campaign { + id BigInt @id + name String + cover_image String? + description String + starts_at DateTime + ends_at DateTime + published Boolean + created_at DateTime @default(now()) + updated_at DateTime @default(now()) + Organisation Organisation @relation(fields: [organisation_id], references: [id]) + organisation_id BigInt + roles CampaignRole[] + questions Question[] +} + +model CampaignRole { + id BigInt @id @default(autoincrement()) + Campaign Campaign @relation(fields: [campaign_id], references: [id]) + campaign_id BigInt + name String + description String? + min_available Int + max_available Int + finalised Boolean + created_at DateTime @default(now()) + updated_at DateTime @default(now()) + Application Application[] +} + +model Question { + id BigInt @id @default(autoincrement()) + title String + description String + required Boolean + created_at DateTime @default(now()) + updated_at DateTime @default(now()) + question_type QuestionType + Campaign Campaign? @relation(fields: [campaignId], references: [id]) + campaignId BigInt? + MultiOptionQuestion MultiOptionQuestion[] + Answer Answer[] +} + +enum QuestionType { + ShortAnswer + MultiChoice + MultiSelect + DropDown +} + +model MultiOptionQuestion { + id BigInt @id @default(autoincrement()) + text String + question Question @relation(fields: [question_id], references: [id]) + question_id BigInt +} + +model Application { + id BigInt @id + Role CampaignRole @relation(fields: [role_id], references: [id]) + role_id BigInt + User User @relation(fields: [user_id], references: [id]) + user_id BigInt + status ApplicationStatus + private_status ApplicationStatus + answers Answer[] + created_at DateTime @default(now()) + updated_at DateTime @default(now()) + ratings Ratings[] +} + +enum ApplicationStatus { + Pending + Rejected + Success +} + +model Answer { + id BigInt @id @default(autoincrement()) + Application Application @relation(fields: [application_id], references: [id]) + application_id BigInt + Question Question @relation(fields: [question_id], references: [id]) + question_id BigInt + shortAnswerAnswers ShortAnswerAnswer[] + multiOptionAnswers MultiOptionAnswer[] +} + +model ShortAnswerAnswer { + id BigInt @id @default(autoincrement()) + text String + Answer Answer @relation(fields: [answer_id], references: [id]) + answer_id BigInt +} + +model MultiOptionAnswer { + id BigInt @id @default(autoincrement()) + option Int + Answer Answer @relation(fields: [answer_id], references: [id]) + answer_id BigInt +} + +model Ratings { + id BigInt @id @default(autoincrement()) + Application Application @relation(fields: [application_id], references: [id]) + application_id BigInt + Rater User @relation(fields: [rater_id], references: [id]) + rater_id BigInt + rating Int + created_at DateTime @default(now()) + updated_at DateTime @default(now()) +} diff --git a/backend/prisma-cli/src/main.rs b/backend/prisma-cli/src/main.rs new file mode 100644 index 000000000..f7580155a --- /dev/null +++ b/backend/prisma-cli/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + prisma_client_rust_cli::run(); +} From aadc37c941bb4d30f13daa1de2f3318dffcced57 Mon Sep 17 00:00:00 2001 From: William Zhang Date: Wed, 25 Oct 2023 17:17:44 +1100 Subject: [PATCH 06/56] fix(backend): add migrations to .gitignore --- backend/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/.gitignore b/backend/.gitignore index c5def5af4..c57a95cb3 100644 --- a/backend/.gitignore +++ b/backend/.gitignore @@ -1,3 +1,4 @@ .env target Cargo.lock +prisma-cli/prisma/migrations From 2c2ce078b96c883e3daed0d866dee6ab6a277e5b Mon Sep 17 00:00:00 2001 From: Kavika <50282464+KavikaPalletenne@users.noreply.github.com> Date: Fri, 27 Oct 2023 19:33:02 +1100 Subject: [PATCH 07/56] fix(backend): add .idea folder to .gitignore --- backend/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/.gitignore b/backend/.gitignore index c57a95cb3..5d9dc7ef4 100644 --- a/backend/.gitignore +++ b/backend/.gitignore @@ -2,3 +2,4 @@ target Cargo.lock prisma-cli/prisma/migrations +/.idea \ No newline at end of file From 888a9f0dffe9cba5d91d7a0701760660b36d3a58 Mon Sep 17 00:00:00 2001 From: Kavika Date: Sun, 11 Feb 2024 15:10:47 +1100 Subject: [PATCH 08/56] Implement extractors for AuthUser and SuperUser (#458) * start implementing authorisation * feat(backend): implement extractor for AuthUser (user id) * feat(backend): implement extractor for SuperUser (user id + authZ) --------- Co-authored-by: kappamalone --- backend/prisma-cli/prisma/schema.prisma | 6 +- backend/server/Cargo.toml | 7 +- backend/server/src/handler/auth.rs | 35 ++++++---- backend/server/src/main.rs | 40 +++++++++-- backend/server/src/models/app.rs | 10 ++- backend/server/src/models/auth.rs | 89 ++++++++++++++++++++++++- backend/server/src/models/mod.rs | 3 +- backend/server/src/models/user.rs | 8 +++ backend/server/src/service/auth.rs | 11 ++- backend/server/src/service/jwt.rs | 38 +++++++++++ backend/server/src/service/mod.rs | 1 + 11 files changed, 218 insertions(+), 30 deletions(-) create mode 100644 backend/server/src/models/user.rs create mode 100644 backend/server/src/service/jwt.rs diff --git a/backend/prisma-cli/prisma/schema.prisma b/backend/prisma-cli/prisma/schema.prisma index b6368e938..801712e54 100644 --- a/backend/prisma-cli/prisma/schema.prisma +++ b/backend/prisma-cli/prisma/schema.prisma @@ -12,15 +12,15 @@ model User { degree_starting_year Int? created_at DateTime @default(now()) updated_at DateTime - role UserRole @default(USER) + role UserRole @default(User) applications Application[] OrganisationAdmins OrganisationAdmins[] Ratings Ratings[] } enum UserRole { - USER - SUPERUSER + User + SuperUser } model Organisation { diff --git a/backend/server/Cargo.toml b/backend/server/Cargo.toml index b1cfda7e3..36cd9a3a6 100644 --- a/backend/server/Cargo.toml +++ b/backend/server/Cargo.toml @@ -8,14 +8,17 @@ edition = "2021" [dependencies] # Primary crates tokio = { version = "1.32.0", features = ["macros", "rt-multi-thread"] } -axum = { version = "0.6.20", features = ["macros"] } +axum = { version = "0.6.20", features = ["macros", "headers"] } +axum-extra = "0.8.0" sqlx = { version = "0.7.1", features = ["runtime-tokio-rustls", "postgres", "time", "uuid"] } # Important secondary crates anyhow = "1.0.75" serde = { version = "1.0.188", features = ["derive"] } -reqwest = "0.11.20" +reqwest = { version = "0.11.20", features = ["json"] } serde_json = "1.0.105" chrono = { version = "0.4.26", features = ["serde"] } oauth2 = "4.4.1" log = "0.4.20" +uuid = { version = "1.5.0", features = ["serde", "v4"] } +jsonwebtoken = "9.1.0" diff --git a/backend/server/src/handler/auth.rs b/backend/server/src/handler/auth.rs index 5ca7f67e2..195fd2cd2 100644 --- a/backend/server/src/handler/auth.rs +++ b/backend/server/src/handler/auth.rs @@ -1,14 +1,14 @@ -use axum::Extension; +use crate::models::app::AppState; +use crate::models::auth::{AuthRequest, UserProfile}; +use crate::service::auth::create_or_get_user_id; use axum::extract::{Query, State}; use axum::http::StatusCode; use axum::response::IntoResponse; +use axum::Extension; use log::error; -use oauth2::{AuthorizationCode, TokenResponse}; use oauth2::basic::BasicClient; use oauth2::reqwest::async_http_client; -use crate::models::app::AppState; -use crate::models::auth::{AuthRequest, UserProfile}; -use crate::service::auth::create_or_get_user_id; +use oauth2::{AuthorizationCode, TokenResponse}; /// This function handles the passing in of the Google OAuth code. After allowing our app the /// requested permissions, the user is redirected to this url on our server, where we use the @@ -16,29 +16,36 @@ use crate::service::auth::create_or_get_user_id; pub async fn google_callback( State(state): State, Query(query): Query, - Extension(oauth_client): Extension + Extension(oauth_client): Extension, ) -> Result { let token = match oauth_client .exchange_code(AuthorizationCode::new(query.code)) .request_async(async_http_client) - .await { + .await + { Ok(res) => res, Err(e) => { error!("An error occured while exchanging Google OAuth code"); - return Err((StatusCode::INTERNAL_SERVER_ERROR, e.to_string())) + return Err((StatusCode::INTERNAL_SERVER_ERROR, e.to_string())); } }; - let profile = match state.ctx.get("https://openidconnect.googleapis.com/v1/userinfo") + let profile = match state + .ctx + .get("https://openidconnect.googleapis.com/v1/userinfo") .bearer_auth(token.access_token().secret().to_owned()) - .send().await { + .send() + .await + { Ok(res) => res, - Err(e) => return Err((StatusCode::INTERNAL_SERVER_ERROR, e.to_string())) + Err(e) => return Err((StatusCode::INTERNAL_SERVER_ERROR, e.to_string())), }; - let profile = profile.json::().await.unwrap(); + // let profile = profile.json::().await?; - let user_id = create_or_get_user_id(profile.email, state.db).await?; + // let user_id = create_or_get_user_id(profile.email, state.db).await?; // TODO: Create a JWT from this user_id and return to the user. -} \ No newline at end of file + Ok("woohoo") +} + diff --git a/backend/server/src/main.rs b/backend/server/src/main.rs index 2eef9c5f5..684dade1d 100644 --- a/backend/server/src/main.rs +++ b/backend/server/src/main.rs @@ -1,12 +1,44 @@ +use std::env; use axum::{routing::get, Router}; - -mod service; -mod models; +use jsonwebtoken::{DecodingKey, EncodingKey}; +use sqlx::postgres::PgPoolOptions; +use models::app::AppState; mod handler; +mod models; +mod service; #[tokio::main] async fn main() { - let app = Router::new().route("/", get(|| async { "Hello, World!" })); + // Initialise DB connection + let db_url = env::var("DATABASE_URL") + .expect("Error getting DATABASE_URL") + .to_string(); + let pool = PgPoolOptions::new() + .max_connections(5) + .connect(db_url.as_str()).await.expect("Cannot connect to database"); + + // Initialise JWT settings + let jwt_secret = env::var("JWT_SECRET") + .expect("Error getting JWT_SECRET") + .to_string(); + // let jwt_secret = "I want to cry"; + let encoding_key = EncodingKey::from_secret(jwt_secret.as_bytes()); + let decoding_key = DecodingKey::from_secret(jwt_secret.as_bytes()); + + // Initialise reqwest client + let ctx = reqwest::Client::new(); + + // Add all data to AppState + let state = AppState { + db: pool, + ctx, + encoding_key, + decoding_key, + }; + + let app = Router::new() + .route("/", get(|| async { "Hello, World!" })) + .with_state(state); axum::Server::bind(&"0.0.0.0:3000".parse().unwrap()) .serve(app.into_make_service()) diff --git a/backend/server/src/models/app.rs b/backend/server/src/models/app.rs index 613683f1b..1672df00f 100644 --- a/backend/server/src/models/app.rs +++ b/backend/server/src/models/app.rs @@ -1,7 +1,11 @@ -use sqlx::{Pool, Postgres}; +use jsonwebtoken::{DecodingKey, EncodingKey}; use reqwest::Client as ReqwestClient; +use sqlx::{Pool, Postgres}; +#[derive(Clone)] pub struct AppState { pub db: Pool, - pub ctx: ReqwestClient -} \ No newline at end of file + pub ctx: ReqwestClient, + pub decoding_key: DecodingKey, + pub encoding_key: EncodingKey, +} diff --git a/backend/server/src/models/auth.rs b/backend/server/src/models/auth.rs index fc35a14e3..f072d4f4b 100644 --- a/backend/server/src/models/auth.rs +++ b/backend/server/src/models/auth.rs @@ -1,11 +1,96 @@ +use axum::{async_trait, headers, http::{self, Request}, RequestPartsExt}; +use axum::extract::{FromRef, FromRequestParts, TypedHeader}; +use axum::http::request::Parts; +use axum::response::{IntoResponse, Redirect, Response}; use serde::{Deserialize, Serialize}; +use crate::models::app::AppState; +use crate::service::auth::is_super_user; +use crate::service::jwt::decode_auth_token; #[derive(Deserialize, Serialize)] pub struct AuthRequest { - pub code: String + pub code: String, } #[derive(Deserialize, Serialize)] pub struct UserProfile { - pub email: String + pub email: String, +} + +pub struct AuthRedirect; + +impl IntoResponse for AuthRedirect { + fn into_response(self) -> Response { + // TODO: Fix this redirect to point to front end login page + Redirect::temporary("/auth/google").into_response() + } +} + +#[derive(Deserialize, Serialize)] +pub struct AuthUser { + pub user_id: i64, +} + +#[async_trait] +impl FromRequestParts for AuthUser +where + AppState: FromRef, + S: Send + Sync, +{ + type Rejection = AuthRedirect; + + async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { + let app_state = AppState::from_ref(state); + let decoding_key = &app_state.decoding_key; + let extracted_cookies = parts + .extract::>() + .await; + + if let Ok(cookies) = extracted_cookies { + let token = cookies.get("auth_token").ok_or(AuthRedirect)?; + let claims = decode_auth_token(token.to_string(), decoding_key).ok_or(AuthRedirect)?; + + Ok(AuthUser { user_id: claims.sub }) + } else { + Err(AuthRedirect) + } + } +} + +#[derive(Deserialize, Serialize)] +pub struct SuperUser { + pub user_id: i64, +} + +#[async_trait] +impl FromRequestParts for SuperUser + where + AppState: FromRef, + S: Send + Sync, +{ + type Rejection = AuthRedirect; + + async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { + let app_state = AppState::from_ref(state); + let decoding_key = &app_state.decoding_key; + let extracted_cookies = parts + .extract::>() + .await; + + if let Ok(cookies) = extracted_cookies { + let token = cookies.get("auth_token").ok_or(AuthRedirect)?; + let claims = decode_auth_token(token.to_string(), decoding_key).ok_or(AuthRedirect)?; + + let pool = &app_state.db; + let possible_user = is_super_user(claims.sub, pool).await; + + if let Ok(is_auth_user) = possible_user { + if is_auth_user { + return Ok(SuperUser { user_id: claims.sub }); + } + } + } + + Err(AuthRedirect) + } } \ No newline at end of file diff --git a/backend/server/src/models/mod.rs b/backend/server/src/models/mod.rs index b1c8d1e75..59a35f064 100644 --- a/backend/server/src/models/mod.rs +++ b/backend/server/src/models/mod.rs @@ -1,2 +1,3 @@ pub mod auth; -pub mod app; \ No newline at end of file +pub mod app; +pub mod user; \ No newline at end of file diff --git a/backend/server/src/models/user.rs b/backend/server/src/models/user.rs new file mode 100644 index 000000000..69f3eac89 --- /dev/null +++ b/backend/server/src/models/user.rs @@ -0,0 +1,8 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Deserialize, Serialize, sqlx::Type, Clone)] +#[sqlx(type_name = "user_role", rename_all = "PascalCase")] +pub enum UserRole { + User, + SuperUser, +} \ No newline at end of file diff --git a/backend/server/src/service/auth.rs b/backend/server/src/service/auth.rs index 16333e6fb..f62847cce 100644 --- a/backend/server/src/service/auth.rs +++ b/backend/server/src/service/auth.rs @@ -1,4 +1,5 @@ use anyhow::Result; +use jsonwebtoken::{DecodingKey, EncodingKey}; use sqlx::{Pool, Postgres}; /// Checks if a user exists in DB based on given email address. If so, their user_id is returned. @@ -11,4 +12,12 @@ pub async fn create_or_get_user_id(email: String, pool: Pool) -> Resul let user_id = 1; return Ok(user_id); -} \ No newline at end of file +} + +pub async fn is_super_user(user_id: i64, pool: &Pool) -> Result { + let is_super_user = sqlx::query!("SELECT EXISTS(SELECT 1 FROM users WHERE id = $1 AND role = $2)", user_id, UserRole::SuperUser) + .fetch_one(pool) + .await?; + + Ok(is_super_user.exists.unwrap()) +} diff --git a/backend/server/src/service/jwt.rs b/backend/server/src/service/jwt.rs new file mode 100644 index 000000000..10c18a778 --- /dev/null +++ b/backend/server/src/service/jwt.rs @@ -0,0 +1,38 @@ +use axum::extract::State; +use jsonwebtoken::{Algorithm, DecodingKey}; +use jsonwebtoken::{decode, Validation}; +use serde::{Deserialize, Serialize}; +use uuid::Uuid; + +use crate::AppState; + +#[derive(Debug, Deserialize, Serialize)] +pub struct AuthorizationJwtPayload { + pub iss: String, // issuer + pub sub: i64, // subject (user's id) + pub jti: Uuid, // id + pub aud: Vec, // audience (uri the JWT is meant for) + + // Time-based validity + pub exp: i64, // expiry (UNIX timestamp) + pub nbf: i64, // not-valid-before (UNIX timestamp) + pub iat: i64, // issued-at (UNIX timestamp) + + pub username: String, // username +} + +pub fn decode_auth_token( + token: String, + decoding_key: &DecodingKey, +) -> Option { + let decode_token = decode::( + token.as_str(), + decoding_key, + &Validation::new(Algorithm::HS256), + ); + + return match decode_token { + Ok(token) => Option::from(token.claims), + Err(_err) => None::, + }; +} diff --git a/backend/server/src/service/mod.rs b/backend/server/src/service/mod.rs index 95b107626..6e59a7bbd 100644 --- a/backend/server/src/service/mod.rs +++ b/backend/server/src/service/mod.rs @@ -1,2 +1,3 @@ pub mod auth; +pub mod jwt; pub mod oauth2; From 03a487777a6294a9df1a50dfecba48d5d7d0acd5 Mon Sep 17 00:00:00 2001 From: Kavika Date: Sun, 11 Feb 2024 16:51:48 +1100 Subject: [PATCH 09/56] OAuth flow account creation/login (#460) * start implementing authorisation * feat(backend): implement extractor for AuthUser (user id) * feat(backend): implement extractor for SuperUser (user id + authZ) * feat(backend): get existing or create new user for Google login * feat(backend): get name from Google user profile * feat(backend): update schema.prisma to include lowercase table names + updated_at default time for users --------- Co-authored-by: kappamalone --- backend/prisma-cli/prisma/schema.prisma | 32 +++++++++++++++++++++---- backend/server/Cargo.toml | 1 + backend/server/src/handler/auth.rs | 6 ++--- backend/server/src/main.rs | 5 ++++ backend/server/src/models/app.rs | 2 ++ backend/server/src/models/auth.rs | 3 ++- backend/server/src/models/user.rs | 2 +- backend/server/src/service/auth.rs | 28 ++++++++++++++++++---- 8 files changed, 66 insertions(+), 13 deletions(-) diff --git a/backend/prisma-cli/prisma/schema.prisma b/backend/prisma-cli/prisma/schema.prisma index 801712e54..7aa3a8941 100644 --- a/backend/prisma-cli/prisma/schema.prisma +++ b/backend/prisma-cli/prisma/schema.prisma @@ -11,11 +11,13 @@ model User { degree_name String? degree_starting_year Int? created_at DateTime @default(now()) - updated_at DateTime + updated_at DateTime @default(now()) role UserRole @default(User) applications Application[] OrganisationAdmins OrganisationAdmins[] - Ratings Ratings[] + Ratings Rating[] + + @@map("users") } enum UserRole { @@ -31,6 +33,8 @@ model Organisation { updated_at DateTime @default(now()) campaigns Campaign[] OrganisationAdmins OrganisationAdmins[] + + @@map("organisations") } model OrganisationAdmins { @@ -40,6 +44,8 @@ model OrganisationAdmins { user_id BigInt @@id([organisation_id, user_id]) + + @@map("organisation_admins") } model Campaign { @@ -56,6 +62,8 @@ model Campaign { organisation_id BigInt roles CampaignRole[] questions Question[] + + @@map("campaigns") } model CampaignRole { @@ -70,6 +78,8 @@ model CampaignRole { created_at DateTime @default(now()) updated_at DateTime @default(now()) Application Application[] + + @@map("campaign_roles") } model Question { @@ -84,6 +94,8 @@ model Question { campaignId BigInt? MultiOptionQuestion MultiOptionQuestion[] Answer Answer[] + + @@map("questions") } enum QuestionType { @@ -98,6 +110,8 @@ model MultiOptionQuestion { text String question Question @relation(fields: [question_id], references: [id]) question_id BigInt + + @@map("multi_option_questions") } model Application { @@ -111,7 +125,9 @@ model Application { answers Answer[] created_at DateTime @default(now()) updated_at DateTime @default(now()) - ratings Ratings[] + ratings Rating[] + + @@map("applications") } enum ApplicationStatus { @@ -128,6 +144,8 @@ model Answer { question_id BigInt shortAnswerAnswers ShortAnswerAnswer[] multiOptionAnswers MultiOptionAnswer[] + + @@map("answers") } model ShortAnswerAnswer { @@ -135,6 +153,8 @@ model ShortAnswerAnswer { text String Answer Answer @relation(fields: [answer_id], references: [id]) answer_id BigInt + + @@map("short_answer_answers") } model MultiOptionAnswer { @@ -142,9 +162,11 @@ model MultiOptionAnswer { option Int Answer Answer @relation(fields: [answer_id], references: [id]) answer_id BigInt + + @@map("multi_option_answers") } -model Ratings { +model Rating { id BigInt @id @default(autoincrement()) Application Application @relation(fields: [application_id], references: [id]) application_id BigInt @@ -153,4 +175,6 @@ model Ratings { rating Int created_at DateTime @default(now()) updated_at DateTime @default(now()) + + @@map("ratings") } diff --git a/backend/server/Cargo.toml b/backend/server/Cargo.toml index 36cd9a3a6..8e21b5ace 100644 --- a/backend/server/Cargo.toml +++ b/backend/server/Cargo.toml @@ -21,4 +21,5 @@ chrono = { version = "0.4.26", features = ["serde"] } oauth2 = "4.4.1" log = "0.4.20" uuid = { version = "1.5.0", features = ["serde", "v4"] } +rs-snowflake = "0.6.0" jsonwebtoken = "9.1.0" diff --git a/backend/server/src/handler/auth.rs b/backend/server/src/handler/auth.rs index 195fd2cd2..e10ddfe19 100644 --- a/backend/server/src/handler/auth.rs +++ b/backend/server/src/handler/auth.rs @@ -1,5 +1,5 @@ use crate::models::app::AppState; -use crate::models::auth::{AuthRequest, UserProfile}; +use crate::models::auth::{AuthRequest, GoogleUserProfile}; use crate::service::auth::create_or_get_user_id; use axum::extract::{Query, State}; use axum::http::StatusCode; @@ -41,9 +41,9 @@ pub async fn google_callback( Err(e) => return Err((StatusCode::INTERNAL_SERVER_ERROR, e.to_string())), }; - // let profile = profile.json::().await?; + let profile = profile.json::().await?; - // let user_id = create_or_get_user_id(profile.email, state.db).await?; + let user_id = create_or_get_user_id(profile.email, profile.name, state.db).await?; // TODO: Create a JWT from this user_id and return to the user. Ok("woohoo") diff --git a/backend/server/src/main.rs b/backend/server/src/main.rs index 684dade1d..31d318cee 100644 --- a/backend/server/src/main.rs +++ b/backend/server/src/main.rs @@ -1,6 +1,7 @@ use std::env; use axum::{routing::get, Router}; use jsonwebtoken::{DecodingKey, EncodingKey}; +use snowflake::SnowflakeIdGenerator; use sqlx::postgres::PgPoolOptions; use models::app::AppState; mod handler; @@ -28,12 +29,16 @@ async fn main() { // Initialise reqwest client let ctx = reqwest::Client::new(); + // Initialise Snowflake Generator + let snowflake_generator = SnowflakeIdGenerator::new(1, 1); + // Add all data to AppState let state = AppState { db: pool, ctx, encoding_key, decoding_key, + snowflake_generator, }; let app = Router::new() diff --git a/backend/server/src/models/app.rs b/backend/server/src/models/app.rs index 1672df00f..4802de136 100644 --- a/backend/server/src/models/app.rs +++ b/backend/server/src/models/app.rs @@ -1,5 +1,6 @@ use jsonwebtoken::{DecodingKey, EncodingKey}; use reqwest::Client as ReqwestClient; +use snowflake::SnowflakeIdGenerator; use sqlx::{Pool, Postgres}; #[derive(Clone)] @@ -8,4 +9,5 @@ pub struct AppState { pub ctx: ReqwestClient, pub decoding_key: DecodingKey, pub encoding_key: EncodingKey, + pub snowflake_generator: SnowflakeIdGenerator, } diff --git a/backend/server/src/models/auth.rs b/backend/server/src/models/auth.rs index f072d4f4b..a2bdb07f1 100644 --- a/backend/server/src/models/auth.rs +++ b/backend/server/src/models/auth.rs @@ -13,7 +13,8 @@ pub struct AuthRequest { } #[derive(Deserialize, Serialize)] -pub struct UserProfile { +pub struct GoogleUserProfile { + pub name: String, pub email: String, } diff --git a/backend/server/src/models/user.rs b/backend/server/src/models/user.rs index 69f3eac89..2a9240683 100644 --- a/backend/server/src/models/user.rs +++ b/backend/server/src/models/user.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; #[derive(Deserialize, Serialize, sqlx::Type, Clone)] -#[sqlx(type_name = "user_role", rename_all = "PascalCase")] +#[sqlx(type_name = "UserRole", rename_all = "PascalCase")] pub enum UserRole { User, SuperUser, diff --git a/backend/server/src/service/auth.rs b/backend/server/src/service/auth.rs index f62847cce..285338fc1 100644 --- a/backend/server/src/service/auth.rs +++ b/backend/server/src/service/auth.rs @@ -1,21 +1,41 @@ use anyhow::Result; use jsonwebtoken::{DecodingKey, EncodingKey}; +use snowflake::SnowflakeIdGenerator; use sqlx::{Pool, Postgres}; +use crate::models::user::UserRole; /// Checks if a user exists in DB based on given email address. If so, their user_id is returned. /// Otherwise, a new user is created in the DB, and the new id is returned. /// This function is used in OAuth flows to login/signup users when they click the /// "Sign in with ___" buttons. The returned user_id will be used to generate a JWT to be /// used as a token for the user's browser. -pub async fn create_or_get_user_id(email: String, pool: Pool) -> Result { - // TODO: See if user (by email) exists in the database and return their id. If not, insert them, and return the new id. +pub async fn create_or_get_user_id(email: String, name: String, pool: Pool, mut snowflake_generator: SnowflakeIdGenerator) -> Result { + let possible_user_id = sqlx::query!("SELECT id FROM users WHERE email = $1", email) + .fetch_optional(&pool) + .await?; + + if let Some(result) = possible_user_id { + return Ok(result.id); + } + + let user_id = snowflake_generator.real_time_generate(); + + let response = sqlx::query!( + "INSERT INTO users (id, email, name) VALUES ($1, $2, $3)", + user_id, email, name + ) + .execute(&pool) + .await?; - let user_id = 1; return Ok(user_id); } pub async fn is_super_user(user_id: i64, pool: &Pool) -> Result { - let is_super_user = sqlx::query!("SELECT EXISTS(SELECT 1 FROM users WHERE id = $1 AND role = $2)", user_id, UserRole::SuperUser) + let is_super_user = sqlx::query!( + "SELECT EXISTS(SELECT 1 FROM users WHERE id = $1 AND role = $2)", + user_id, + UserRole::SuperUser as UserRole + ) .fetch_one(pool) .await?; From f442048671cc7b603f88acf95f2fb00c7895c94b Mon Sep 17 00:00:00 2001 From: Kavika Date: Fri, 29 Mar 2024 11:16:12 +1100 Subject: [PATCH 10/56] fix(backend): Add dotenvy to server and prisma (#466) --- backend/prisma-cli/Cargo.toml | 1 + backend/prisma-cli/src/main.rs | 1 + backend/server/Cargo.toml | 1 + backend/server/src/main.rs | 7 ++++++- 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/backend/prisma-cli/Cargo.toml b/backend/prisma-cli/Cargo.toml index 585fc7090..b7a1ed541 100644 --- a/backend/prisma-cli/Cargo.toml +++ b/backend/prisma-cli/Cargo.toml @@ -9,6 +9,7 @@ edition = "2021" prisma-client-rust-cli = { git = "https://github.com/Brendonovich/prisma-client-rust", tag = "0.6.10", features = [ "postgresql", ] } +dotenvy = "0.15.7" [alias] prisma = "run --bin prisma-cli --" diff --git a/backend/prisma-cli/src/main.rs b/backend/prisma-cli/src/main.rs index f7580155a..bb2046192 100644 --- a/backend/prisma-cli/src/main.rs +++ b/backend/prisma-cli/src/main.rs @@ -1,3 +1,4 @@ fn main() { + dotenvy::dotenv().unwrap(); prisma_client_rust_cli::run(); } diff --git a/backend/server/Cargo.toml b/backend/server/Cargo.toml index 8e21b5ace..856713151 100644 --- a/backend/server/Cargo.toml +++ b/backend/server/Cargo.toml @@ -23,3 +23,4 @@ log = "0.4.20" uuid = { version = "1.5.0", features = ["serde", "v4"] } rs-snowflake = "0.6.0" jsonwebtoken = "9.1.0" +dotenvy = "0.15.7" diff --git a/backend/server/src/main.rs b/backend/server/src/main.rs index 31d318cee..b2f70ddf0 100644 --- a/backend/server/src/main.rs +++ b/backend/server/src/main.rs @@ -1,4 +1,5 @@ use std::env; +use anyhow::Result; use axum::{routing::get, Router}; use jsonwebtoken::{DecodingKey, EncodingKey}; use snowflake::SnowflakeIdGenerator; @@ -9,7 +10,9 @@ mod models; mod service; #[tokio::main] -async fn main() { +async fn main() -> Result<()> { + dotenvy::dotenv()?; + // Initialise DB connection let db_url = env::var("DATABASE_URL") .expect("Error getting DATABASE_URL") @@ -49,4 +52,6 @@ async fn main() { .serve(app.into_make_service()) .await .unwrap(); + + Ok(()) } From 88da78238aefc877ad191dc20df8c204a410117b Mon Sep 17 00:00:00 2001 From: Kavika Date: Fri, 29 Mar 2024 13:36:56 +1100 Subject: [PATCH 11/56] feat(ci): add postgres and migration to actions workflow (#467) --- .github/workflows/rust.yml | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 7e324eb04..94c7bdae6 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -12,11 +12,20 @@ env: jobs: build: runs-on: ubuntu-latest + services: + postgres: + image: postgres:16 + env: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: password + POSTGRES_DB: chaos + ports: + - 5432:5432 steps: - uses: actions/checkout@v4 - - name: Mock an env file + - name: Setup env file run: | - echo "DATABASE_URL=test_url" >> backend/.env + echo "DATABASE_URL=postgres://postgres:password@localhost:5432/chaos" >> backend/.env echo "JWT_SECRET=test_secret" >> backend/.env echo "GOOGLE_CLIENT_ID=test" >> backend/.env echo "GOOGLE_CLIENT_SECRET=test" >> backend/.env @@ -31,15 +40,15 @@ jobs: - uses: Swatinem/rust-cache@v2 with: working-directory: backend/ + - name: Migrate DB + working-directory: ./prisma-cli + run: cargo run db push - name: Build - run: cargo build --manifest-path backend/server/Cargo.toml + working-directory: ./server + run: cargo build - name: Cargo Clippy - run: cargo clippy --manifest-path backend/server/Cargo.toml + working-directory: ./server + run: cargo clippy - name: RustFmt + working-directory: ./server run: cargo fmt --manifest-path backend/server/Cargo.toml - - name: Build - run: cargo build --manifest-path backend/seed_data/Cargo.toml - - name: Cargo Clippy - run: cargo clippy --manifest-path backend/seed_data/Cargo.toml - - name: RustFmt - run: cargo fmt --manifest-path backend/seed_data/Cargo.toml From 7398aa203e4d3eb6ea386bc608706315848effb6 Mon Sep 17 00:00:00 2001 From: Kavika Date: Fri, 29 Mar 2024 13:40:15 +1100 Subject: [PATCH 12/56] fix(ci): Fix incorrect working directory in Rust workflow file (#468) * feat(ci): add postgres and migration to actions workflow * fix(ci): fix incorrect working directory --- .github/workflows/rust.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 94c7bdae6..c6d862fac 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -41,13 +41,13 @@ jobs: with: working-directory: backend/ - name: Migrate DB - working-directory: ./prisma-cli + working-directory: backend/prisma-cli run: cargo run db push - name: Build - working-directory: ./server + working-directory: backend/server run: cargo build - name: Cargo Clippy - working-directory: ./server + working-directory: backend/server run: cargo clippy - name: RustFmt working-directory: ./server From 0e75ddf3058363173989bcbaaf876f350eb58de2 Mon Sep 17 00:00:00 2001 From: Kavika Date: Fri, 29 Mar 2024 13:45:35 +1100 Subject: [PATCH 13/56] fix(ci): Fix build errors and cargo fmt/clippy (#469) * feat(ci): add postgres and migration to actions workflow * fix(ci): fix incorrect working directory * fix(ci): ran cargo fmt and fix build errors --- backend/server/src/handler/auth.rs | 12 +++++++--- backend/server/src/handler/mod.rs | 2 +- backend/server/src/main.rs | 8 ++++--- backend/server/src/models/auth.rs | 36 +++++++++++++++------------- backend/server/src/models/mod.rs | 4 ++-- backend/server/src/models/user.rs | 2 +- backend/server/src/service/auth.rs | 35 ++++++++++++++++----------- backend/server/src/service/jwt.rs | 8 +++---- backend/server/src/service/oauth2.rs | 13 ++++------ 9 files changed, 67 insertions(+), 53 deletions(-) diff --git a/backend/server/src/handler/auth.rs b/backend/server/src/handler/auth.rs index e10ddfe19..fe6effee3 100644 --- a/backend/server/src/handler/auth.rs +++ b/backend/server/src/handler/auth.rs @@ -41,11 +41,17 @@ pub async fn google_callback( Err(e) => return Err((StatusCode::INTERNAL_SERVER_ERROR, e.to_string())), }; - let profile = profile.json::().await?; + let profile = profile.json::().await.unwrap(); - let user_id = create_or_get_user_id(profile.email, profile.name, state.db).await?; + let user_id = create_or_get_user_id( + profile.email, + profile.name, + state.db, + state.snowflake_generator, + ) + .await + .unwrap(); // TODO: Create a JWT from this user_id and return to the user. Ok("woohoo") } - diff --git a/backend/server/src/handler/mod.rs b/backend/server/src/handler/mod.rs index 5696e21f9..0e4a05d59 100644 --- a/backend/server/src/handler/mod.rs +++ b/backend/server/src/handler/mod.rs @@ -1 +1 @@ -pub mod auth; \ No newline at end of file +pub mod auth; diff --git a/backend/server/src/main.rs b/backend/server/src/main.rs index b2f70ddf0..e9d844819 100644 --- a/backend/server/src/main.rs +++ b/backend/server/src/main.rs @@ -1,10 +1,10 @@ -use std::env; use anyhow::Result; use axum::{routing::get, Router}; use jsonwebtoken::{DecodingKey, EncodingKey}; +use models::app::AppState; use snowflake::SnowflakeIdGenerator; use sqlx::postgres::PgPoolOptions; -use models::app::AppState; +use std::env; mod handler; mod models; mod service; @@ -19,7 +19,9 @@ async fn main() -> Result<()> { .to_string(); let pool = PgPoolOptions::new() .max_connections(5) - .connect(db_url.as_str()).await.expect("Cannot connect to database"); + .connect(db_url.as_str()) + .await + .expect("Cannot connect to database"); // Initialise JWT settings let jwt_secret = env::var("JWT_SECRET") diff --git a/backend/server/src/models/auth.rs b/backend/server/src/models/auth.rs index a2bdb07f1..3fb447bbc 100644 --- a/backend/server/src/models/auth.rs +++ b/backend/server/src/models/auth.rs @@ -1,11 +1,15 @@ -use axum::{async_trait, headers, http::{self, Request}, RequestPartsExt}; +use crate::models::app::AppState; +use crate::service::auth::is_super_user; +use crate::service::jwt::decode_auth_token; use axum::extract::{FromRef, FromRequestParts, TypedHeader}; use axum::http::request::Parts; use axum::response::{IntoResponse, Redirect, Response}; +use axum::{ + async_trait, headers, + http::{self, Request}, + RequestPartsExt, +}; use serde::{Deserialize, Serialize}; -use crate::models::app::AppState; -use crate::service::auth::is_super_user; -use crate::service::jwt::decode_auth_token; #[derive(Deserialize, Serialize)] pub struct AuthRequest { @@ -43,15 +47,15 @@ where async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { let app_state = AppState::from_ref(state); let decoding_key = &app_state.decoding_key; - let extracted_cookies = parts - .extract::>() - .await; + let extracted_cookies = parts.extract::>().await; if let Ok(cookies) = extracted_cookies { let token = cookies.get("auth_token").ok_or(AuthRedirect)?; let claims = decode_auth_token(token.to_string(), decoding_key).ok_or(AuthRedirect)?; - Ok(AuthUser { user_id: claims.sub }) + Ok(AuthUser { + user_id: claims.sub, + }) } else { Err(AuthRedirect) } @@ -65,18 +69,16 @@ pub struct SuperUser { #[async_trait] impl FromRequestParts for SuperUser - where - AppState: FromRef, - S: Send + Sync, +where + AppState: FromRef, + S: Send + Sync, { type Rejection = AuthRedirect; async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { let app_state = AppState::from_ref(state); let decoding_key = &app_state.decoding_key; - let extracted_cookies = parts - .extract::>() - .await; + let extracted_cookies = parts.extract::>().await; if let Ok(cookies) = extracted_cookies { let token = cookies.get("auth_token").ok_or(AuthRedirect)?; @@ -87,11 +89,13 @@ impl FromRequestParts for SuperUser if let Ok(is_auth_user) = possible_user { if is_auth_user { - return Ok(SuperUser { user_id: claims.sub }); + return Ok(SuperUser { + user_id: claims.sub, + }); } } } Err(AuthRedirect) } -} \ No newline at end of file +} diff --git a/backend/server/src/models/mod.rs b/backend/server/src/models/mod.rs index 59a35f064..2164071c9 100644 --- a/backend/server/src/models/mod.rs +++ b/backend/server/src/models/mod.rs @@ -1,3 +1,3 @@ -pub mod auth; pub mod app; -pub mod user; \ No newline at end of file +pub mod auth; +pub mod user; diff --git a/backend/server/src/models/user.rs b/backend/server/src/models/user.rs index 2a9240683..1f99f52f1 100644 --- a/backend/server/src/models/user.rs +++ b/backend/server/src/models/user.rs @@ -5,4 +5,4 @@ use serde::{Deserialize, Serialize}; pub enum UserRole { User, SuperUser, -} \ No newline at end of file +} diff --git a/backend/server/src/service/auth.rs b/backend/server/src/service/auth.rs index 285338fc1..d4ecf3ecf 100644 --- a/backend/server/src/service/auth.rs +++ b/backend/server/src/service/auth.rs @@ -1,15 +1,20 @@ +use crate::models::user::UserRole; use anyhow::Result; use jsonwebtoken::{DecodingKey, EncodingKey}; use snowflake::SnowflakeIdGenerator; use sqlx::{Pool, Postgres}; -use crate::models::user::UserRole; /// Checks if a user exists in DB based on given email address. If so, their user_id is returned. /// Otherwise, a new user is created in the DB, and the new id is returned. /// This function is used in OAuth flows to login/signup users when they click the /// "Sign in with ___" buttons. The returned user_id will be used to generate a JWT to be /// used as a token for the user's browser. -pub async fn create_or_get_user_id(email: String, name: String, pool: Pool, mut snowflake_generator: SnowflakeIdGenerator) -> Result { +pub async fn create_or_get_user_id( + email: String, + name: String, + pool: Pool, + mut snowflake_generator: SnowflakeIdGenerator, +) -> Result { let possible_user_id = sqlx::query!("SELECT id FROM users WHERE email = $1", email) .fetch_optional(&pool) .await?; @@ -21,23 +26,25 @@ pub async fn create_or_get_user_id(email: String, name: String, pool: Pool) -> Result { let is_super_user = sqlx::query!( - "SELECT EXISTS(SELECT 1 FROM users WHERE id = $1 AND role = $2)", - user_id, - UserRole::SuperUser as UserRole - ) - .fetch_one(pool) - .await?; + "SELECT EXISTS(SELECT 1 FROM users WHERE id = $1 AND role = $2)", + user_id, + UserRole::SuperUser as UserRole + ) + .fetch_one(pool) + .await?; Ok(is_super_user.exists.unwrap()) } diff --git a/backend/server/src/service/jwt.rs b/backend/server/src/service/jwt.rs index 10c18a778..272e6aed3 100644 --- a/backend/server/src/service/jwt.rs +++ b/backend/server/src/service/jwt.rs @@ -1,6 +1,6 @@ use axum::extract::State; -use jsonwebtoken::{Algorithm, DecodingKey}; use jsonwebtoken::{decode, Validation}; +use jsonwebtoken::{Algorithm, DecodingKey}; use serde::{Deserialize, Serialize}; use uuid::Uuid; @@ -9,7 +9,7 @@ use crate::AppState; #[derive(Debug, Deserialize, Serialize)] pub struct AuthorizationJwtPayload { pub iss: String, // issuer - pub sub: i64, // subject (user's id) + pub sub: i64, // subject (user's id) pub jti: Uuid, // id pub aud: Vec, // audience (uri the JWT is meant for) @@ -31,8 +31,8 @@ pub fn decode_auth_token( &Validation::new(Algorithm::HS256), ); - return match decode_token { + match decode_token { Ok(token) => Option::from(token.claims), Err(_err) => None::, - }; + } } diff --git a/backend/server/src/service/oauth2.rs b/backend/server/src/service/oauth2.rs index 92e60c420..673379fce 100644 --- a/backend/server/src/service/oauth2.rs +++ b/backend/server/src/service/oauth2.rs @@ -1,11 +1,5 @@ -use oauth2::{ - AuthUrl, - ClientId, - ClientSecret, - RedirectUrl, - TokenUrl -}; use oauth2::basic::BasicClient; +use oauth2::{AuthUrl, ClientId, ClientSecret, RedirectUrl, TokenUrl}; use std::env; /// Returns a oauth2::BasicClient, setup with settings for CHAOS Google OAuth. @@ -26,5 +20,6 @@ pub fn build_oauth_client(client_id: String, client_secret: String) -> BasicClie Some(ClientSecret::new(client_secret)), auth_url, Some(token_url), - ).set_redirect_uri(RedirectUrl::new(redirect_url).unwrap()) -} \ No newline at end of file + ) + .set_redirect_uri(RedirectUrl::new(redirect_url).unwrap()) +} From 9ee127c64055332246c6c5e1aaa063d124b58ae6 Mon Sep 17 00:00:00 2001 From: Kavika Date: Fri, 29 Mar 2024 13:54:16 +1100 Subject: [PATCH 14/56] fix(ci): rust-cache keys and cargo fmt working directory fix (#470) * feat(ci): add postgres and migration to actions workflow * fix(ci): fix incorrect working directory * fix(ci): ran cargo fmt and fix build errors * fix(ci): Incorrect working directory for cargo fmt * fix(ci): rust-cache keys --- .github/workflows/rust.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index c6d862fac..07d873f1e 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -38,8 +38,6 @@ jobs: profile: minimal toolchain: stable - uses: Swatinem/rust-cache@v2 - with: - working-directory: backend/ - name: Migrate DB working-directory: backend/prisma-cli run: cargo run db push @@ -50,5 +48,5 @@ jobs: working-directory: backend/server run: cargo clippy - name: RustFmt - working-directory: ./server + working-directory: backend/server run: cargo fmt --manifest-path backend/server/Cargo.toml From 7e9d7c73a3b6ae95eedd8b8e9e69723123d58a60 Mon Sep 17 00:00:00 2001 From: Kavika Date: Fri, 29 Mar 2024 13:59:21 +1100 Subject: [PATCH 15/56] fix(ci): rust-cache workspaces fix (#471) * feat(ci): add postgres and migration to actions workflow * fix(ci): fix incorrect working directory * fix(ci): ran cargo fmt and fix build errors * fix(ci): Incorrect working directory for cargo fmt * fix(ci): rust-cache keys * fix(ci): add workspaces to rust-cache --- .github/workflows/rust.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 07d873f1e..63c45995d 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -38,6 +38,10 @@ jobs: profile: minimal toolchain: stable - uses: Swatinem/rust-cache@v2 + with: + workspaces: | + prisma-cli + server - name: Migrate DB working-directory: backend/prisma-cli run: cargo run db push From 70eda4b5f933c5996f32c56f1df9b40fb5fe9bae Mon Sep 17 00:00:00 2001 From: Kavika Date: Fri, 29 Mar 2024 14:00:36 +1100 Subject: [PATCH 16/56] fix(ci): cargo fmt remove manifest-path arg (#472) * feat(ci): add postgres and migration to actions workflow * fix(ci): fix incorrect working directory * fix(ci): ran cargo fmt and fix build errors * fix(ci): Incorrect working directory for cargo fmt * fix(ci): rust-cache keys * fix(ci): add workspaces to rust-cache * fix(ci): cargo fmt remove manifest-path arg --- .github/workflows/rust.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 63c45995d..2bfbc1511 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -53,4 +53,4 @@ jobs: run: cargo clippy - name: RustFmt working-directory: backend/server - run: cargo fmt --manifest-path backend/server/Cargo.toml + run: cargo fmt From 46b104d67eff7dc76e9c45ba037dfc7c0caddb3d Mon Sep 17 00:00:00 2001 From: Kavika Date: Sat, 6 Apr 2024 00:55:56 +1100 Subject: [PATCH 17/56] API Spec for Users and Organisations (#477) * fix(ci): run CI on rewrite branch pull request * feat(docs): added endpoint docs for org and users --- .github/workflows/rust.yml | 2 +- backend/api.yaml | 408 +++++++++++++++++++++++++++++++++++++ 2 files changed, 409 insertions(+), 1 deletion(-) create mode 100644 backend/api.yaml diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 2bfbc1511..fe8c05d7d 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -2,7 +2,7 @@ name: Rust on: pull_request: - branches: [main, "renovate/*"] + branches: [main, "renovate/*", "CHAOS-224-KHAOS-rewrite"] push: branches: ["renovate/*"] diff --git a/backend/api.yaml b/backend/api.yaml new file mode 100644 index 000000000..c6567fc9d --- /dev/null +++ b/backend/api.yaml @@ -0,0 +1,408 @@ +openapi: "3.0.0" +info: + title: Chaos API + version: 1.0.0 +servers: + - url: https://chaos.csesoc.app/api + description: Production server + - url: http://localhost:3000/api + description: Local server + +paths: + /user: + get: + description: Returns info about currently logged in user. + tags: + - User + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + id: + type: integer + format: int64 + example: 1541815603606036480 + email: + type: string + example: me@example.com + zid: + type: string + example: z5555555 + name: + type: string + example: Clancy Lion + degree_name: + type: string + example: Computer Science + degree_starting_year: + type: integer + example: 2024 + role: + type: string + example: User + '401': + description: Not logged in. + content: + application/json: + schema: + properties: + error: + type: string + example: Not logged in. + delete: + description: Deletes currently logged in user. + tags: + - User + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + message: + type: string + example: Successfully deleted user. + '403': + description: User is only admin of an organisation. + content: + application/json: + schema: + properties: + error: + type: string + example: "Cannot delete sole admin of an organisation." + '401': + description: Not logged. + content: + application/json: + schema: + properties: + error: + type: string + example: Not logged in. + /user/{id}: + get: + parameters: + - name: id + in: path + description: User ID + required: true + schema: + type: integer + format: int64 + description: Returns info about specified user. + tags: + - User + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + id: + type: integer + format: int64 + example: 1541815603606036480 + email: + type: string + example: me@example.com + zid: + type: string + example: z5555555 + name: + type: string + example: Clancy Lion + degree_name: + type: string + example: Computer Science + degree_starting_year: + type: integer + example: 2024 + '403': + description: Requested user has not applied to one of authorized user's campaign. + content: + application/json: + schema: + properties: + error: + type: string + example: "Insufficient permissions" + /user/name: + patch: + description: Updates currently logged in user's name. + tags: + - User + requestBody: + required: true + content: + application/json: + schema: + properties: + name: + type: string + example: "Clancy Tiger" + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + message: + type: string + example: Successfully updated name. + '401': + description: Not logged in. + content: + application/json: + schema: + properties: + error: + type: string + example: Not logged in. + /user/zid: + patch: + description: Updates currently logged in user's zID. + tags: + - User + requestBody: + required: true + content: + application/json: + schema: + properties: + zid: + type: string + example: "z5123456" + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + message: + type: string + example: Successfully updated zID. + '401': + description: Not logged in. + content: + application/json: + schema: + properties: + error: + type: string + example: Not logged in. + /user/degree: + patch: + description: Updates currently logged in user's degree. + tags: + - User + requestBody: + required: true + content: + application/json: + schema: + properties: + degree_name: + type: string + example: "Electrical Engineering" + degree_starting_year: + type: integer + example: 2024 + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + message: + type: string + example: Successfully updated email. + '401': + description: Not logged in. + content: + application/json: + schema: + properties: + error: + type: string + example: Not logged in. + /organisation/{id}: + get: + parameters: + - name: id + in: path + description: Organisation ID + required: true + schema: + type: integer + format: int64 + description: Returns info about specified organisation. + tags: + - Organisation + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + id: + type: integer + format: int64 + example: 6996987893965262849 + name: + type: string + example: UNSW Software Development Society + logo: + type: string + example: "76718252-2a13-4de2-bc07-f977c75dc52b" + created_at: + type: string + example: 2024-02-10T18:25:43.511Z + /organisation/{id}/campaigns: + get: + parameters: + - name: id + in: path + description: Organisation ID + required: true + schema: + type: integer + format: int64 + description: Returns active campaigns for specified organisation. + tags: + - Organisation + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + campaigns: + type: array + items: + type: object + properties: + id: + type: integer + format: int64 + example: 6996987893965262849 + name: + type: string + example: 2024 Subcommittee Recruitment + cover_image: + type: string + example: 2d19617b-46fd-4927-9f53-77d69232ba5d + description: + type: string + example: Are you excited to make a difference? + starts_at: + type: string + example: 2024-03-15T18:25:43.511Z + ends_at: + type: string + example: 2024-04-15T18:25:43.511Z + /organisation/{id}/logo: + patch: + parameters: + - name: id + in: path + description: Organisation ID + required: true + schema: + type: integer + format: int64 + description: Updates logo for specified organistion. + tags: + - Organisation + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + message: + type: string + example: Successfully updated logo. + '401': + description: Not logged in. + content: + application/json: + schema: + properties: + error: + type: string + example: Not logged in. + '403': + description: User is not an organisation admin. + content: + application/json: + schema: + properties: + error: + type: string + example: Unauthorised. + /organisation/{id}/members: + put: + parameters: + - name: id + in: path + description: Organisation ID + required: true + schema: + type: integer + format: int64 + requestBody: + required: true + content: + application/json: + schema: + properties: + members: + type: array + items: + uniqueItems: true + type: integer + format: int64 + example: [1541815603606036480, 1541815603606036827, 1541815287306036429] + description: Specifies members for specified organistion. + tags: + - Organisation + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + message: + type: string + example: Successfully updated members. + '401': + description: Not logged in. + content: + application/json: + schema: + properties: + error: + type: string + example: Not logged in. + '403': + description: User is not an organisation admin. + content: + application/json: + schema: + properties: + error: + type: string + example: Unauthorised. \ No newline at end of file From 8ef0ccaf70b9c7f4b18d29bf2f52bbd711e858ee Mon Sep 17 00:00:00 2001 From: Kavika Date: Sat, 6 Apr 2024 13:24:13 +1100 Subject: [PATCH 18/56] Draft API Documentation for User, Organisation and Campaign (#478) * feat(docs): updates to user and organisation api spec * feat(docs): draft spec for campaign api * fix(ci): update rust workflow to use actions/cache --- .github/workflows/rust.yml | 18 +- backend/api.yaml | 405 ++++++++++++++++++++++++++++++++++++- 2 files changed, 414 insertions(+), 9 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index fe8c05d7d..59dc859e1 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -3,6 +3,9 @@ name: Rust on: pull_request: branches: [main, "renovate/*", "CHAOS-224-KHAOS-rewrite"] + paths: + - backend/server/** + - backend/prisma-cli/** push: branches: ["renovate/*"] @@ -37,11 +40,18 @@ jobs: with: profile: minimal toolchain: stable - - uses: Swatinem/rust-cache@v2 + - name: Setup cargo cache + uses: actions/cache@v3 with: - workspaces: | - prisma-cli - server + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + backend/prisma-cli/target/ + backend/server/target/ + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + restore-keys: ${{ runner.os }}-cargo- - name: Migrate DB working-directory: backend/prisma-cli run: cargo run db push diff --git a/backend/api.yaml b/backend/api.yaml index c6567fc9d..cb80ef4fa 100644 --- a/backend/api.yaml +++ b/backend/api.yaml @@ -9,6 +9,21 @@ servers: description: Local server paths: + /auth/logout: + post: + description: Invalidates current token. + tags: + - Auth + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + messages: + type: string + example: Successfully logged out. /user: get: description: Returns info about currently logged in user. @@ -234,6 +249,44 @@ paths: error: type: string example: Not logged in. + /organisation: + post: + description: Creates a new organisation. + tags: + - Organisation + requestBody: + required: true + content: + application/json: + schema: + properties: + name: + type: string + example: "UNSW Software Development Society" + admin: + type: integer + format: int64 + example: 1541815603606036480 + description: User ID of admin + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + message: + type: string + example: Successfully created organisation. + '403': + description: User is not a super user. + content: + application/json: + schema: + properties: + error: + type: string + example: Unauthorized /organisation/{id}: get: parameters: @@ -267,6 +320,37 @@ paths: created_at: type: string example: 2024-02-10T18:25:43.511Z + delete: + parameters: + - name: id + in: path + description: Organisation ID + required: true + schema: + type: integer + format: int64 + description: Deletes specified organisation. + tags: + - Organisation + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + message: + type: string + example: Successfully deleted organisation. + '403': + description: User is not a super user. + content: + application/json: + schema: + properties: + error: + type: string + example: Unauthorized /organisation/{id}/campaigns: get: parameters: @@ -331,9 +415,10 @@ paths: application/json: schema: properties: - message: + upload_url: type: string - example: Successfully updated logo. + description: Presigned S3 url to upload file. + example: https://presignedurldemo.s3.eu-west-2.amazonaws.com/6996987893965262849/2d19617b-46fd-4927-9f53-77d69232ba5d?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJJWZ7B6WCRGMKFGQ%2F20180210%2Feu-west-2%2Fs3%2Faws4_request&X-Amz-Date=20180210T171315Z&X-Amz-Expires=1800&X-Amz-Signature=12b74b0788aa036bc7c3d03b3f20c61f1f91cc9ad8873e3314255dc479a25351&X-Amz-SignedHeaders=host '401': description: Not logged in. content: @@ -351,8 +436,48 @@ paths: properties: error: type: string - example: Unauthorised. + example: Unauthorized /organisation/{id}/members: + get: + parameters: + - name: id + in: path + description: Organisation ID + required: true + schema: + type: integer + format: int64 + description: Returns list of members of specified organisation. + tags: + - Organisation + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + members: + type: array + items: + type: object + properties: + id: + type: integer + format: int64 + example: 1541815603606036480 + name: + type: string + example: Clancy Lion + '403': + description: User is not an organisation admin or member. + content: + application/json: + schema: + properties: + error: + type: string + example: Unauthorized put: parameters: - name: id @@ -370,8 +495,8 @@ paths: properties: members: type: array + uniqueItems: true items: - uniqueItems: true type: integer format: int64 example: [1541815603606036480, 1541815603606036827, 1541815287306036429] @@ -405,4 +530,274 @@ paths: properties: error: type: string - example: Unauthorised. \ No newline at end of file + example: Unauthorized + /organisation/{id}/campaign: + post: + parameters: + - name: id + in: path + description: Organisation ID + required: true + schema: + type: integer + format: int64 + description: Creates a new campaign inside specified organisation. + tags: + - Organisation + requestBody: + required: true + content: + application/json: + schema: + properties: + name: + type: string + example: 2024 Subcommittee Recruitment + description: + type: string + example: Are you excited to make a difference? + starts_at: + type: string + example: 2024-03-15T18:25:43.511Z + ends_at: + type: string + example: 2024-04-15T18:25:43.511Z + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + message: + type: string + example: Successfully created campaign. + '403': + description: User is not an admin of specified organisation. + content: + application/json: + schema: + properties: + error: + type: string + example: Unauthorized + /campaign: + get: + description: Returns all active campaigns. + tags: + - Campaign + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + campaigns: + type: array + items: + type: object + properties: + id: + type: integer + format: int64 + example: 6996987893965262849 + organisation_id: + type: integer + format: int64 + example: 1541815603606036827 + organisation_name: + type: string + example: UNSW Software Development Society + name: + type: string + example: 2024 Subcommittee Recruitment + cover_image: + type: string + example: 2d19617b-46fd-4927-9f53-77d69232ba5d + description: + type: string + example: Are you excited to make a difference? + starts_at: + type: string + example: 2024-03-15T18:25:43.511Z + ends_at: + type: string + example: 2024-04-15T18:25:43.511Z + /campaign/{id}: + get: + parameters: + - name: id + in: path + description: Campaign ID + required: true + schema: + type: integer + format: int64 + description: Returns info about specified campaign. + tags: + - Campaign + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + id: + type: integer + format: int64 + example: 6996987893965262849 + organisation_id: + type: integer + format: int64 + example: 1541815603606036827 + organisation_name: + type: string + example: UNSW Software Development Society + name: + type: string + example: 2024 Subcommittee Recruitment + cover_image: + type: string + example: 2d19617b-46fd-4927-9f53-77d69232ba5d + description: + type: string + example: Are you excited to make a difference? + starts_at: + type: string + example: 2024-03-15T18:25:43.511Z + ends_at: + type: string + example: 2024-04-15T18:25:43.511Z + put: + parameters: + - name: id + in: path + description: Campaign ID + required: true + schema: + type: integer + format: int64 + requestBody: + required: true + content: + application/json: + schema: + properties: + name: + type: string + example: 2024 Subcommittee Recruitment + description: + type: string + example: Are you excited to make a difference? + starts_at: + type: string + example: 2024-03-15T18:25:43.511Z + ends_at: + type: string + example: 2024-04-15T18:25:43.511Z + description: Updates details of specified campaign. + tags: + - Campaign + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + message: + type: string + example: Successfully updated campaign. + '401': + description: Not logged in. + content: + application/json: + schema: + properties: + error: + type: string + example: Not logged in. + '403': + description: User is not an organisation admin. + content: + application/json: + schema: + properties: + error: + type: string + example: Unauthorized + delete: + parameters: + - name: id + in: path + description: Campaign ID + required: true + schema: + type: integer + format: int64 + description: Deletes specified campaign. + tags: + - Campaign + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + message: + type: string + example: Successfully deleted campaign. + '403': + description: User is not an admin of campaign's organisation. + content: + application/json: + schema: + properties: + error: + type: string + example: Unauthorized + /campaign/{id}/banner: + patch: + parameters: + - name: id + in: path + description: Campaign ID + required: true + schema: + type: integer + format: int64 + description: Updates banner image for specified campaign. + tags: + - Campaign + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + upload_url: + type: string + description: Presigned S3 url to upload file. + example: https://presignedurldemo.s3.eu-west-2.amazonaws.com/6996987893965262849/2d19617b-46fd-4927-9f53-77d69232ba5d?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJJWZ7B6WCRGMKFGQ%2F20180210%2Feu-west-2%2Fs3%2Faws4_request&X-Amz-Date=20180210T171315Z&X-Amz-Expires=1800&X-Amz-Signature=12b74b0788aa036bc7c3d03b3f20c61f1f91cc9ad8873e3314255dc479a25351&X-Amz-SignedHeaders=host + '401': + description: Not logged in. + content: + application/json: + schema: + properties: + error: + type: string + example: Not logged in. + '403': + description: User is not an organisation admin. + content: + application/json: + schema: + properties: + error: + type: string + example: Unauthorized \ No newline at end of file From 80556babb921d731cee3e9eb9249c07cf54f9498 Mon Sep 17 00:00:00 2001 From: Kavika Date: Sat, 6 Apr 2024 14:53:19 +1100 Subject: [PATCH 19/56] feat(backend): Switch from Prisma schema to SQL schema (#479) * feat(backend): create sql migrations * feat(backend): remove prisma schema * fix(ci): change from prisma migration to sql * fix(ci): no default sqlx-cli features * fix(backend): remove duplicate primary key for applications * fix(backend): rename migrations to prepend 'create' * fix(ci): check for cached sqlx before installing with cargo * fix(ci): remove ci run on specific paths --- .github/workflows/rust.yml | 11 +- .../20240406023149_create_users.sql | 13 ++ .../20240406024211_create_organisations.sql | 18 ++ .../20240406025537_create_campaigns.sql | 33 ++++ .../20240406031400_create_questions.sql | 28 +++ .../20240406031915_create_applications.sql | 99 ++++++++++ backend/prisma-cli/Cargo.toml | 15 -- backend/prisma-cli/prisma/schema.prisma | 180 ------------------ backend/prisma-cli/src/main.rs | 4 - 9 files changed, 196 insertions(+), 205 deletions(-) create mode 100644 backend/migrations/20240406023149_create_users.sql create mode 100644 backend/migrations/20240406024211_create_organisations.sql create mode 100644 backend/migrations/20240406025537_create_campaigns.sql create mode 100644 backend/migrations/20240406031400_create_questions.sql create mode 100644 backend/migrations/20240406031915_create_applications.sql delete mode 100644 backend/prisma-cli/Cargo.toml delete mode 100644 backend/prisma-cli/prisma/schema.prisma delete mode 100644 backend/prisma-cli/src/main.rs diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 59dc859e1..8788bb704 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -3,9 +3,6 @@ name: Rust on: pull_request: branches: [main, "renovate/*", "CHAOS-224-KHAOS-rewrite"] - paths: - - backend/server/** - - backend/prisma-cli/** push: branches: ["renovate/*"] @@ -48,13 +45,15 @@ jobs: ~/.cargo/registry/index/ ~/.cargo/registry/cache/ ~/.cargo/git/db/ - backend/prisma-cli/target/ backend/server/target/ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} restore-keys: ${{ runner.os }}-cargo- - name: Migrate DB - working-directory: backend/prisma-cli - run: cargo run db push + working-directory: backend + run: | + which sqlx || cargo install sqlx-cli --no-default-features --features native-tls,postgres + sqlx database create + sqlx migrate run - name: Build working-directory: backend/server run: cargo build diff --git a/backend/migrations/20240406023149_create_users.sql b/backend/migrations/20240406023149_create_users.sql new file mode 100644 index 000000000..6dd68b695 --- /dev/null +++ b/backend/migrations/20240406023149_create_users.sql @@ -0,0 +1,13 @@ +CREATE TYPE user_role AS ENUM ('User', 'SuperUser'); + +CREATE TABLE users ( + id BIGINT PRIMARY KEY, + email TEXT NOT NULL UNIQUE, + zid TEXT, + name TEXT NOT NULL, + degree_name TEXT, + degree_starting_year INTEGER, + role user_role NOT NULL, + created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP +); diff --git a/backend/migrations/20240406024211_create_organisations.sql b/backend/migrations/20240406024211_create_organisations.sql new file mode 100644 index 000000000..6ba4bbcab --- /dev/null +++ b/backend/migrations/20240406024211_create_organisations.sql @@ -0,0 +1,18 @@ +CREATE TABLE organisations ( + id BIGINT PRIMARY KEY, + name TEXT NOT NULL UNIQUE, + logo TEXT, + created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP +); + +CREATE TABLE organisation_admins ( + id SERIAL PRIMARY KEY, + organisation_id BIGINT NOT NULL, + user_id BIGINT NOT NULL, + CONSTRAINT FK_organisation_admins_organisation + FOREIGN KEY(organisation_id) + REFERENCES organisations(id) + ON DELETE CASCADE + ON UPDATE CASCADE +) diff --git a/backend/migrations/20240406025537_create_campaigns.sql b/backend/migrations/20240406025537_create_campaigns.sql new file mode 100644 index 000000000..0bffeb164 --- /dev/null +++ b/backend/migrations/20240406025537_create_campaigns.sql @@ -0,0 +1,33 @@ +CREATE TABLE campaigns ( + id BIGINT PRIMARY KEY, + organisation_id BIGINT NOT NULL, + name TEXT NOT NULL, + cover_image TEXT, + description TEXT, + starts_at TIMESTAMPTZ NOT NULL, + ends_at TIMESTAMPTZ NOT NULL, + created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, + CONSTRAINT FK_campaigns_organisations + FOREIGN KEY(organisation_id) + REFERENCES organisations(id) + ON DELETE CASCADE + ON UPDATE CASCADE +); + +CREATE TABLE campaign_roles ( + id SERIAL PRIMARY KEY, + campaign_id BIGINT NOT NULL, + name TEXT NOT NULL, + description TEXT, + min_available INTEGER, + max_available INTEGER, + finalised BOOLEAN, + created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, + CONSTRAINT FK_campaign_roles_campaign + FOREIGN KEY(campaign_id) + REFERENCES campaigns(id) + ON DELETE CASCADE + ON UPDATE CASCADE +) diff --git a/backend/migrations/20240406031400_create_questions.sql b/backend/migrations/20240406031400_create_questions.sql new file mode 100644 index 000000000..2e2bb3508 --- /dev/null +++ b/backend/migrations/20240406031400_create_questions.sql @@ -0,0 +1,28 @@ +CREATE TYPE question_type AS ENUM ('ShortAnswer', 'MultiChoice', 'MultiSelect', 'DropDown'); + +CREATE TABLE questions ( + id BIGINT PRIMARY KEY, + title TEXT NOT NULL, + description TEXT, + required BOOLEAN, + question_type question_type NOT NULL, + campaign_id BIGINT NOT NULL, + created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, + CONSTRAINT FK_questions_campaigns + FOREIGN KEY(campaign_id) + REFERENCES campaigns(id) + ON DELETE CASCADE + ON UPDATE CASCADE +); + +CREATE TABLE multi_option_question_options ( + id SERIAL PRIMARY KEY, + text TEXT NOT NULL, + question_id INTEGER NOT NULL, + CONSTRAINT FK_multi_option_question_options_questions + FOREIGN KEY(question_id) + REFERENCES questions(id) + ON DELETE CASCADE + ON UPDATE CASCADE +) diff --git a/backend/migrations/20240406031915_create_applications.sql b/backend/migrations/20240406031915_create_applications.sql new file mode 100644 index 000000000..e39ede9fa --- /dev/null +++ b/backend/migrations/20240406031915_create_applications.sql @@ -0,0 +1,99 @@ +CREATE TYPE application_status AS ENUM ('Pending', 'Rejected', 'Successful'); + +CREATE TABLE applications ( + id BIGINT PRIMARY KEY, + campaign_id BIGINT NOT NULL, + user_id BIGINT NOT NULL, + status application_status NOT NULL, + private_status application_status NOT NULL, + created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, + CONSTRAINT FK_applications_campaigns + FOREIGN KEY(campaign_id) + REFERENCES campaigns(id) + ON DELETE CASCADE + ON UPDATE CASCADE, + CONSTRAINT FK_applications_users + FOREIGN KEY(user_id) + REFERENCES users(id) + ON DELETE CASCADE + ON UPDATE CASCADE +); + +CREATE TABLE application_roles ( + id SERIAL PRIMARY KEY, + application_id INTEGER NOT NULL, + campaign_role_id INTEGER NOT NULL, + CONSTRAINT FK_application_roles_applications + FOREIGN KEY(application_id) + REFERENCES applications(id) + ON DELETE CASCADE + ON UPDATE CASCADE, + CONSTRAINT FK_application_roles_campaign_roles + FOREIGN KEY(campaign_role_id) + REFERENCES campaign_roles(id) + ON DELETE CASCADE + ON UPDATE CASCADE +); + +CREATE TABLE answers ( + id SERIAL PRIMARY KEY, + application_id BIGINT NOT NULL, + question_id BIGINT NOT NULL, + CONSTRAINT FK_answers_applications + FOREIGN KEY(application_id) + REFERENCES applications(id) + ON DELETE CASCADE + ON UPDATE CASCADE, + CONSTRAINT FK_answers_questions + FOREIGN KEY(question_id) + REFERENCES questions(id) + ON DELETE CASCADE + ON UPDATE CASCADE +); + +CREATE TABLE short_answer_answers ( + id SERIAL PRIMARY KEY, + text TEXT NOT NULL, + answer_id INTEGER NOT NULL, + CONSTRAINT FK_multi_option_answer_options_answers + FOREIGN KEY(answer_id) + REFERENCES answers(id) + ON DELETE CASCADE + ON UPDATE CASCADE +); + +CREATE TABLE multi_option_answer_options ( + id SERIAL PRIMARY KEY, + option_id BIGINT NOT NULL, + answer_id INTEGER NOT NULL, + CONSTRAINT FK_multi_option_answer_options_question_options + FOREIGN KEY(option_id) + REFERENCES multi_option_question_options(id) + ON DELETE CASCADE + ON UPDATE CASCADE, + CONSTRAINT FK_multi_option_answer_options_answers + FOREIGN KEY(answer_id) + REFERENCES answers(id) + ON DELETE CASCADE + ON UPDATE CASCADE +); + +CREATE TABLE application_ratings ( + id SERIAL PRIMARY KEY, + application_id BIGINT NOT NULL, + rater_id BIGINT NOT NULL, + rating INTEGER NOT NULL, + created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, + CONSTRAINT FK_application_ratings_applications + FOREIGN KEY(application_id) + REFERENCES applications(id) + ON DELETE CASCADE + ON UPDATE CASCADE, + CONSTRAINT FK_application_ratings_users + FOREIGN KEY(rater_id) + REFERENCES users(id) + ON DELETE CASCADE + ON UPDATE CASCADE +); diff --git a/backend/prisma-cli/Cargo.toml b/backend/prisma-cli/Cargo.toml deleted file mode 100644 index b7a1ed541..000000000 --- a/backend/prisma-cli/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "prisma-cli" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -prisma-client-rust-cli = { git = "https://github.com/Brendonovich/prisma-client-rust", tag = "0.6.10", features = [ - "postgresql", -] } -dotenvy = "0.15.7" - -[alias] -prisma = "run --bin prisma-cli --" diff --git a/backend/prisma-cli/prisma/schema.prisma b/backend/prisma-cli/prisma/schema.prisma deleted file mode 100644 index 7aa3a8941..000000000 --- a/backend/prisma-cli/prisma/schema.prisma +++ /dev/null @@ -1,180 +0,0 @@ -datasource db { - provider = "postgresql" - url = env("DATABASE_URL") -} - -model User { - id BigInt @id - email String @unique - zid String? - name String - degree_name String? - degree_starting_year Int? - created_at DateTime @default(now()) - updated_at DateTime @default(now()) - role UserRole @default(User) - applications Application[] - OrganisationAdmins OrganisationAdmins[] - Ratings Rating[] - - @@map("users") -} - -enum UserRole { - User - SuperUser -} - -model Organisation { - id BigInt @id - name String - logo String? - created_at DateTime @default(now()) - updated_at DateTime @default(now()) - campaigns Campaign[] - OrganisationAdmins OrganisationAdmins[] - - @@map("organisations") -} - -model OrganisationAdmins { - Organisation Organisation @relation(fields: [organisation_id], references: [id]) - organisation_id BigInt - User User @relation(fields: [user_id], references: [id]) - user_id BigInt - - @@id([organisation_id, user_id]) - - @@map("organisation_admins") -} - -model Campaign { - id BigInt @id - name String - cover_image String? - description String - starts_at DateTime - ends_at DateTime - published Boolean - created_at DateTime @default(now()) - updated_at DateTime @default(now()) - Organisation Organisation @relation(fields: [organisation_id], references: [id]) - organisation_id BigInt - roles CampaignRole[] - questions Question[] - - @@map("campaigns") -} - -model CampaignRole { - id BigInt @id @default(autoincrement()) - Campaign Campaign @relation(fields: [campaign_id], references: [id]) - campaign_id BigInt - name String - description String? - min_available Int - max_available Int - finalised Boolean - created_at DateTime @default(now()) - updated_at DateTime @default(now()) - Application Application[] - - @@map("campaign_roles") -} - -model Question { - id BigInt @id @default(autoincrement()) - title String - description String - required Boolean - created_at DateTime @default(now()) - updated_at DateTime @default(now()) - question_type QuestionType - Campaign Campaign? @relation(fields: [campaignId], references: [id]) - campaignId BigInt? - MultiOptionQuestion MultiOptionQuestion[] - Answer Answer[] - - @@map("questions") -} - -enum QuestionType { - ShortAnswer - MultiChoice - MultiSelect - DropDown -} - -model MultiOptionQuestion { - id BigInt @id @default(autoincrement()) - text String - question Question @relation(fields: [question_id], references: [id]) - question_id BigInt - - @@map("multi_option_questions") -} - -model Application { - id BigInt @id - Role CampaignRole @relation(fields: [role_id], references: [id]) - role_id BigInt - User User @relation(fields: [user_id], references: [id]) - user_id BigInt - status ApplicationStatus - private_status ApplicationStatus - answers Answer[] - created_at DateTime @default(now()) - updated_at DateTime @default(now()) - ratings Rating[] - - @@map("applications") -} - -enum ApplicationStatus { - Pending - Rejected - Success -} - -model Answer { - id BigInt @id @default(autoincrement()) - Application Application @relation(fields: [application_id], references: [id]) - application_id BigInt - Question Question @relation(fields: [question_id], references: [id]) - question_id BigInt - shortAnswerAnswers ShortAnswerAnswer[] - multiOptionAnswers MultiOptionAnswer[] - - @@map("answers") -} - -model ShortAnswerAnswer { - id BigInt @id @default(autoincrement()) - text String - Answer Answer @relation(fields: [answer_id], references: [id]) - answer_id BigInt - - @@map("short_answer_answers") -} - -model MultiOptionAnswer { - id BigInt @id @default(autoincrement()) - option Int - Answer Answer @relation(fields: [answer_id], references: [id]) - answer_id BigInt - - @@map("multi_option_answers") -} - -model Rating { - id BigInt @id @default(autoincrement()) - Application Application @relation(fields: [application_id], references: [id]) - application_id BigInt - Rater User @relation(fields: [rater_id], references: [id]) - rater_id BigInt - rating Int - created_at DateTime @default(now()) - updated_at DateTime @default(now()) - - @@map("ratings") -} diff --git a/backend/prisma-cli/src/main.rs b/backend/prisma-cli/src/main.rs deleted file mode 100644 index bb2046192..000000000 --- a/backend/prisma-cli/src/main.rs +++ /dev/null @@ -1,4 +0,0 @@ -fn main() { - dotenvy::dotenv().unwrap(); - prisma_client_rust_cli::run(); -} From c1b4fb76ca5481d046338ed97bd8c502ef6e25a7 Mon Sep 17 00:00:00 2001 From: Kavika Date: Sun, 7 Apr 2024 11:10:11 +1000 Subject: [PATCH 20/56] fix(backend): Create index on lower(email) --- backend/migrations/20240406023149_create_users.sql | 2 ++ backend/server/src/service/auth.rs | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/backend/migrations/20240406023149_create_users.sql b/backend/migrations/20240406023149_create_users.sql index 6dd68b695..0bb4cd8b3 100644 --- a/backend/migrations/20240406023149_create_users.sql +++ b/backend/migrations/20240406023149_create_users.sql @@ -11,3 +11,5 @@ CREATE TABLE users ( created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP ); + +CREATE UNIQUE INDEX IDX_users_email_lower on users ((lower(email))); diff --git a/backend/server/src/service/auth.rs b/backend/server/src/service/auth.rs index d4ecf3ecf..70b1bc0c0 100644 --- a/backend/server/src/service/auth.rs +++ b/backend/server/src/service/auth.rs @@ -15,7 +15,7 @@ pub async fn create_or_get_user_id( pool: Pool, mut snowflake_generator: SnowflakeIdGenerator, ) -> Result { - let possible_user_id = sqlx::query!("SELECT id FROM users WHERE email = $1", email) + let possible_user_id = sqlx::query!("SELECT id FROM users WHERE lower(email) = $1", email.to_lowercase()) .fetch_optional(&pool) .await?; @@ -28,7 +28,7 @@ pub async fn create_or_get_user_id( let response = sqlx::query!( "INSERT INTO users (id, email, name) VALUES ($1, $2, $3)", user_id, - email, + email.to_lowercase(), name ) .execute(&pool) From 048f0fe0b8c23ddac22df11a73ec61f139964c25 Mon Sep 17 00:00:00 2001 From: Kavika Date: Sun, 7 Apr 2024 11:34:59 +1000 Subject: [PATCH 21/56] Update backend README.md --- backend/README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/backend/README.md b/backend/README.md index 4135e0b4d..3ac95fbcf 100644 --- a/backend/README.md +++ b/backend/README.md @@ -31,8 +31,7 @@ Request -> Middleware (optional) -> Handler -> Service -> Middleware (Optional) - [Axum](https://github.com/tokio-rs/axum) ### Persistence -- [SQLx](https://github.com/launchbadge/sqlx) - Queries -- [Prisma](https://www.prisma.io/) - Migrations and Schema +- [SQLx](https://github.com/launchbadge/sqlx) - Queries and Migrations - PostgreSQL ### AuthN @@ -42,4 +41,4 @@ Request -> Middleware (optional) -> Handler -> Service -> Middleware (Optional) - JWT ### Storage -- Local file system +- Object storage From d6d581a043f59e0bf33c9568b35cb9e744711c39 Mon Sep 17 00:00:00 2001 From: Kavika Date: Sun, 7 Apr 2024 14:10:57 +1000 Subject: [PATCH 22/56] feat(backend): Rust error handling with anyhow & custom types (#482) * feat(db): add indexes for foreign key reference columns * fix(db): index naming and missing semicolons * dep(backend): update axum * fix(backend): remove testing jwt handlers * feat(backend): Add custom jwt validator and header * feat(backend): basic error handling enum * fix(backend): ran cargo fmt * fix(backend): remove unused imports --- .../20240406024211_create_organisations.sql | 4 +- .../20240406025537_create_campaigns.sql | 4 +- .../20240406031400_create_questions.sql | 4 +- .../20240406031915_create_applications.sql | 16 ++++- backend/server/Cargo.toml | 30 ++++---- backend/server/src/handler/auth.rs | 37 +++++----- backend/server/src/main.rs | 17 +++-- backend/server/src/models/app.rs | 4 +- backend/server/src/models/auth.rs | 68 ++++++++++--------- backend/server/src/models/error.rs | 33 +++++++++ backend/server/src/models/mod.rs | 1 + backend/server/src/service/auth.rs | 14 ++-- backend/server/src/service/jwt.rs | 39 ++++++++--- backend/server/src/service/oauth2.rs | 3 +- 14 files changed, 179 insertions(+), 95 deletions(-) create mode 100644 backend/server/src/models/error.rs diff --git a/backend/migrations/20240406024211_create_organisations.sql b/backend/migrations/20240406024211_create_organisations.sql index 6ba4bbcab..88dda366d 100644 --- a/backend/migrations/20240406024211_create_organisations.sql +++ b/backend/migrations/20240406024211_create_organisations.sql @@ -15,4 +15,6 @@ CREATE TABLE organisation_admins ( REFERENCES organisations(id) ON DELETE CASCADE ON UPDATE CASCADE -) +); + +CREATE INDEX IDX_organisation_admins_organisation on organisation_admins (organisation_id); diff --git a/backend/migrations/20240406025537_create_campaigns.sql b/backend/migrations/20240406025537_create_campaigns.sql index 0bffeb164..46bca9df2 100644 --- a/backend/migrations/20240406025537_create_campaigns.sql +++ b/backend/migrations/20240406025537_create_campaigns.sql @@ -30,4 +30,6 @@ CREATE TABLE campaign_roles ( REFERENCES campaigns(id) ON DELETE CASCADE ON UPDATE CASCADE -) +); + +CREATE INDEX IDX_campaign_roles_campaign on campaign_roles (campaign_id); diff --git a/backend/migrations/20240406031400_create_questions.sql b/backend/migrations/20240406031400_create_questions.sql index 2e2bb3508..fa1708132 100644 --- a/backend/migrations/20240406031400_create_questions.sql +++ b/backend/migrations/20240406031400_create_questions.sql @@ -25,4 +25,6 @@ CREATE TABLE multi_option_question_options ( REFERENCES questions(id) ON DELETE CASCADE ON UPDATE CASCADE -) +); + +CREATE INDEX IDX_multi_option_question_options_questions on multi_option_question_options (question_id); diff --git a/backend/migrations/20240406031915_create_applications.sql b/backend/migrations/20240406031915_create_applications.sql index e39ede9fa..91d9edcf4 100644 --- a/backend/migrations/20240406031915_create_applications.sql +++ b/backend/migrations/20240406031915_create_applications.sql @@ -36,6 +36,9 @@ CREATE TABLE application_roles ( ON UPDATE CASCADE ); +CREATE INDEX IDX_application_roles_applications on application_roles (application_id); +CREATE INDEX IDX_application_roles_campaign_roles on application_roles (campaign_role_id); + CREATE TABLE answers ( id SERIAL PRIMARY KEY, application_id BIGINT NOT NULL, @@ -52,17 +55,22 @@ CREATE TABLE answers ( ON UPDATE CASCADE ); +CREATE INDEX IDX_answers_applications on answers (application_id); +CREATE INDEX IDX_answers_questions on answers (question_id); + CREATE TABLE short_answer_answers ( id SERIAL PRIMARY KEY, text TEXT NOT NULL, answer_id INTEGER NOT NULL, - CONSTRAINT FK_multi_option_answer_options_answers + CONSTRAINT FK_short_answer_answers_answers FOREIGN KEY(answer_id) REFERENCES answers(id) ON DELETE CASCADE ON UPDATE CASCADE ); +CREATE INDEX IDX_short_answer_answers_answers on short_answer_answers (answer_id); + CREATE TABLE multi_option_answer_options ( id SERIAL PRIMARY KEY, option_id BIGINT NOT NULL, @@ -79,6 +87,9 @@ CREATE TABLE multi_option_answer_options ( ON UPDATE CASCADE ); +CREATE INDEX IDX_multi_option_answer_options_question_options on multi_option_answer_options (option_id); +CREATE INDEX IDX_multi_option_answer_options_answers on multi_option_answer_options (answer_id); + CREATE TABLE application_ratings ( id SERIAL PRIMARY KEY, application_id BIGINT NOT NULL, @@ -97,3 +108,6 @@ CREATE TABLE application_ratings ( ON DELETE CASCADE ON UPDATE CASCADE ); + +CREATE INDEX IDX_application_ratings_applications on application_ratings (application_id); +CREATE INDEX IDX_application_ratings_users on application_ratings (rater_id); diff --git a/backend/server/Cargo.toml b/backend/server/Cargo.toml index 856713151..fd7647485 100644 --- a/backend/server/Cargo.toml +++ b/backend/server/Cargo.toml @@ -7,20 +7,20 @@ edition = "2021" [dependencies] # Primary crates -tokio = { version = "1.32.0", features = ["macros", "rt-multi-thread"] } -axum = { version = "0.6.20", features = ["macros", "headers"] } -axum-extra = "0.8.0" -sqlx = { version = "0.7.1", features = ["runtime-tokio-rustls", "postgres", "time", "uuid"] } +tokio = { version = "1.34", features = ["macros", "rt-multi-thread"] } +axum = { version = "0.7", features = ["macros"] } +axum-extra = { version = "0.9", features = ["typed-header"] } +sqlx = { version = "0.7", features = ["runtime-tokio-rustls", "postgres", "time", "uuid"] } # Important secondary crates -anyhow = "1.0.75" -serde = { version = "1.0.188", features = ["derive"] } -reqwest = { version = "0.11.20", features = ["json"] } -serde_json = "1.0.105" -chrono = { version = "0.4.26", features = ["serde"] } -oauth2 = "4.4.1" -log = "0.4.20" -uuid = { version = "1.5.0", features = ["serde", "v4"] } -rs-snowflake = "0.6.0" -jsonwebtoken = "9.1.0" -dotenvy = "0.15.7" +anyhow = "1.0" +serde = { version = "1.0", features = ["derive"] } +reqwest = { version = "0.11", features = ["json"] } +serde_json = "1.0" +chrono = { version = "0.4", features = ["serde"] } +oauth2 = "4.4" +log = "0.4" +uuid = { version = "1.5", features = ["serde", "v4"] } +rs-snowflake = "0.6" +jsonwebtoken = "9.1" +dotenvy = "0.15" diff --git a/backend/server/src/handler/auth.rs b/backend/server/src/handler/auth.rs index fe6effee3..12fcab02a 100644 --- a/backend/server/src/handler/auth.rs +++ b/backend/server/src/handler/auth.rs @@ -1,11 +1,11 @@ use crate::models::app::AppState; use crate::models::auth::{AuthRequest, GoogleUserProfile}; +use crate::models::error::ChaosError; use crate::service::auth::create_or_get_user_id; +use crate::service::jwt::encode_auth_token; use axum::extract::{Query, State}; -use axum::http::StatusCode; use axum::response::IntoResponse; use axum::Extension; -use log::error; use oauth2::basic::BasicClient; use oauth2::reqwest::async_http_client; use oauth2::{AuthorizationCode, TokenResponse}; @@ -17,34 +17,23 @@ pub async fn google_callback( State(state): State, Query(query): Query, Extension(oauth_client): Extension, -) -> Result { - let token = match oauth_client +) -> Result { + let token = oauth_client .exchange_code(AuthorizationCode::new(query.code)) .request_async(async_http_client) - .await - { - Ok(res) => res, - Err(e) => { - error!("An error occured while exchanging Google OAuth code"); - return Err((StatusCode::INTERNAL_SERVER_ERROR, e.to_string())); - } - }; + .await?; - let profile = match state + let profile = state .ctx .get("https://openidconnect.googleapis.com/v1/userinfo") .bearer_auth(token.access_token().secret().to_owned()) .send() - .await - { - Ok(res) => res, - Err(e) => return Err((StatusCode::INTERNAL_SERVER_ERROR, e.to_string())), - }; + .await?; let profile = profile.json::().await.unwrap(); let user_id = create_or_get_user_id( - profile.email, + profile.email.clone(), profile.name, state.db, state.snowflake_generator, @@ -52,6 +41,12 @@ pub async fn google_callback( .await .unwrap(); - // TODO: Create a JWT from this user_id and return to the user. - Ok("woohoo") + // TODO: Return JWT as set-cookie header. + let token = encode_auth_token( + profile.email, + user_id, + &state.encoding_key, + &state.jwt_header, + ); + Ok(token) } diff --git a/backend/server/src/main.rs b/backend/server/src/main.rs index e9d844819..8d91e4b04 100644 --- a/backend/server/src/main.rs +++ b/backend/server/src/main.rs @@ -1,10 +1,12 @@ use anyhow::Result; use axum::{routing::get, Router}; -use jsonwebtoken::{DecodingKey, EncodingKey}; +use jsonwebtoken::{Algorithm, DecodingKey, EncodingKey, Header, Validation}; use models::app::AppState; use snowflake::SnowflakeIdGenerator; use sqlx::postgres::PgPoolOptions; use std::env; +use crate::handler::auth::google_callback; + mod handler; mod models; mod service; @@ -30,6 +32,10 @@ async fn main() -> Result<()> { // let jwt_secret = "I want to cry"; let encoding_key = EncodingKey::from_secret(jwt_secret.as_bytes()); let decoding_key = DecodingKey::from_secret(jwt_secret.as_bytes()); + let jwt_header = Header::new(Algorithm::HS512); + let mut jwt_validator = Validation::new(Algorithm::HS512); + jwt_validator.set_issuer(&["Chaos"]); + jwt_validator.set_audience(&["chaos.devsoc.app"]); // Initialise reqwest client let ctx = reqwest::Client::new(); @@ -43,17 +49,18 @@ async fn main() -> Result<()> { ctx, encoding_key, decoding_key, + jwt_header, + jwt_validator, snowflake_generator, }; let app = Router::new() .route("/", get(|| async { "Hello, World!" })) + .route("/api/auth/callback/google", get(google_callback)) .with_state(state); - axum::Server::bind(&"0.0.0.0:3000".parse().unwrap()) - .serve(app.into_make_service()) - .await - .unwrap(); + let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); + axum::serve(listener, app).await.unwrap(); Ok(()) } diff --git a/backend/server/src/models/app.rs b/backend/server/src/models/app.rs index 4802de136..9fbd2a8e8 100644 --- a/backend/server/src/models/app.rs +++ b/backend/server/src/models/app.rs @@ -1,4 +1,4 @@ -use jsonwebtoken::{DecodingKey, EncodingKey}; +use jsonwebtoken::{DecodingKey, EncodingKey, Header, Validation}; use reqwest::Client as ReqwestClient; use snowflake::SnowflakeIdGenerator; use sqlx::{Pool, Postgres}; @@ -9,5 +9,7 @@ pub struct AppState { pub ctx: ReqwestClient, pub decoding_key: DecodingKey, pub encoding_key: EncodingKey, + pub jwt_header: Header, + pub jwt_validator: Validation, pub snowflake_generator: SnowflakeIdGenerator, } diff --git a/backend/server/src/models/auth.rs b/backend/server/src/models/auth.rs index 3fb447bbc..149c3a25b 100644 --- a/backend/server/src/models/auth.rs +++ b/backend/server/src/models/auth.rs @@ -1,14 +1,15 @@ use crate::models::app::AppState; +use crate::models::error::ChaosError; use crate::service::auth::is_super_user; use crate::service::jwt::decode_auth_token; -use axum::extract::{FromRef, FromRequestParts, TypedHeader}; +use axum::extract::{FromRef, FromRequestParts}; use axum::http::request::Parts; use axum::response::{IntoResponse, Redirect, Response}; use axum::{ - async_trait, headers, - http::{self, Request}, + async_trait, RequestPartsExt, }; +use axum_extra::{headers::Cookie, TypedHeader}; use serde::{Deserialize, Serialize}; #[derive(Deserialize, Serialize)] @@ -42,23 +43,25 @@ where AppState: FromRef, S: Send + Sync, { - type Rejection = AuthRedirect; + type Rejection = ChaosError; async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { let app_state = AppState::from_ref(state); let decoding_key = &app_state.decoding_key; - let extracted_cookies = parts.extract::>().await; + let jwt_validator = &app_state.jwt_validator; + let TypedHeader(cookies) = parts + .extract::>() + .await + .map_err(|_| ChaosError::NotLoggedIn)?; - if let Ok(cookies) = extracted_cookies { - let token = cookies.get("auth_token").ok_or(AuthRedirect)?; - let claims = decode_auth_token(token.to_string(), decoding_key).ok_or(AuthRedirect)?; + let token = cookies.get("auth_token").ok_or(ChaosError::NotLoggedIn)?; - Ok(AuthUser { - user_id: claims.sub, - }) - } else { - Err(AuthRedirect) - } + let claims = + decode_auth_token(token, decoding_key, jwt_validator).ok_or(ChaosError::NotLoggedIn)?; + + Ok(AuthUser { + user_id: claims.sub, + }) } } @@ -73,29 +76,32 @@ where AppState: FromRef, S: Send + Sync, { - type Rejection = AuthRedirect; + type Rejection = ChaosError; async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { let app_state = AppState::from_ref(state); let decoding_key = &app_state.decoding_key; - let extracted_cookies = parts.extract::>().await; - - if let Ok(cookies) = extracted_cookies { - let token = cookies.get("auth_token").ok_or(AuthRedirect)?; - let claims = decode_auth_token(token.to_string(), decoding_key).ok_or(AuthRedirect)?; - - let pool = &app_state.db; - let possible_user = is_super_user(claims.sub, pool).await; - - if let Ok(is_auth_user) = possible_user { - if is_auth_user { - return Ok(SuperUser { - user_id: claims.sub, - }); - } + let jwt_validator = &app_state.jwt_validator; + let TypedHeader(cookies) = parts + .extract::>() + .await + .map_err(|_| ChaosError::NotLoggedIn)?; + + let token = cookies.get("auth_token").ok_or(ChaosError::NotLoggedIn)?; + + let claims = + decode_auth_token(token, decoding_key, jwt_validator).ok_or(ChaosError::NotLoggedIn)?; + let pool = &app_state.db; + let possible_user = is_super_user(claims.sub, pool).await; + + if let Ok(is_auth_user) = possible_user { + if is_auth_user { + return Ok(SuperUser { + user_id: claims.sub, + }); } } - Err(AuthRedirect) + Err(ChaosError::NotLoggedIn) } } diff --git a/backend/server/src/models/error.rs b/backend/server/src/models/error.rs new file mode 100644 index 000000000..ca160d978 --- /dev/null +++ b/backend/server/src/models/error.rs @@ -0,0 +1,33 @@ +use axum::http::StatusCode; +use axum::response::{IntoResponse, Redirect, Response}; + +/// Custom error enum for Chaos. +/// +/// Handles all anyhow errors (when `?` is used) alongside +/// specific errors for business logic. +pub enum ChaosError { + NotLoggedIn, + Unauthorized, + ForbiddenOperation, + ServerError(anyhow::Error), +} + +impl IntoResponse for ChaosError { + fn into_response(self) -> Response { + match self { + ChaosError::NotLoggedIn => Redirect::temporary("/auth/google").into_response(), + ChaosError::Unauthorized => (StatusCode::UNAUTHORIZED, "Unauthorized").into_response(), + ChaosError::ForbiddenOperation => (StatusCode::FORBIDDEN, "Forbidden operation").into_response(), + ChaosError::ServerError(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()).into_response() + } + } +} + +impl From for ChaosError +where + E: Into, +{ + fn from(err: E) -> Self { + ChaosError::ServerError(err.into()) + } +} diff --git a/backend/server/src/models/mod.rs b/backend/server/src/models/mod.rs index 2164071c9..b992e0f91 100644 --- a/backend/server/src/models/mod.rs +++ b/backend/server/src/models/mod.rs @@ -1,3 +1,4 @@ pub mod app; pub mod auth; +pub mod error; pub mod user; diff --git a/backend/server/src/service/auth.rs b/backend/server/src/service/auth.rs index 70b1bc0c0..7da5a35b1 100644 --- a/backend/server/src/service/auth.rs +++ b/backend/server/src/service/auth.rs @@ -1,8 +1,7 @@ -use crate::models::user::UserRole; use anyhow::Result; -use jsonwebtoken::{DecodingKey, EncodingKey}; use snowflake::SnowflakeIdGenerator; use sqlx::{Pool, Postgres}; +use crate::models::user::UserRole; /// Checks if a user exists in DB based on given email address. If so, their user_id is returned. /// Otherwise, a new user is created in the DB, and the new id is returned. @@ -15,9 +14,12 @@ pub async fn create_or_get_user_id( pool: Pool, mut snowflake_generator: SnowflakeIdGenerator, ) -> Result { - let possible_user_id = sqlx::query!("SELECT id FROM users WHERE lower(email) = $1", email.to_lowercase()) - .fetch_optional(&pool) - .await?; + let possible_user_id = sqlx::query!( + "SELECT id FROM users WHERE lower(email) = $1", + email.to_lowercase() + ) + .fetch_optional(&pool) + .await?; if let Some(result) = possible_user_id { return Ok(result.id); @@ -25,7 +27,7 @@ pub async fn create_or_get_user_id( let user_id = snowflake_generator.real_time_generate(); - let response = sqlx::query!( + sqlx::query!( "INSERT INTO users (id, email, name) VALUES ($1, $2, $3)", user_id, email.to_lowercase(), diff --git a/backend/server/src/service/jwt.rs b/backend/server/src/service/jwt.rs index 272e6aed3..c7db35cbb 100644 --- a/backend/server/src/service/jwt.rs +++ b/backend/server/src/service/jwt.rs @@ -1,11 +1,9 @@ -use axum::extract::State; -use jsonwebtoken::{decode, Validation}; -use jsonwebtoken::{Algorithm, DecodingKey}; +use jsonwebtoken::{decode, encode, EncodingKey, Header, Validation}; +use jsonwebtoken::DecodingKey; use serde::{Deserialize, Serialize}; +use std::time::{Duration, SystemTime, UNIX_EPOCH}; use uuid::Uuid; -use crate::AppState; - #[derive(Debug, Deserialize, Serialize)] pub struct AuthorizationJwtPayload { pub iss: String, // issuer @@ -21,15 +19,34 @@ pub struct AuthorizationJwtPayload { pub username: String, // username } +pub fn encode_auth_token( + username: String, + user_id: i64, + encoding_key: &EncodingKey, + jwt_header: &Header, +) -> String { + let current_time = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); + let expiry = i64::try_from((current_time + Duration::from_secs(604800)).as_secs()).unwrap(); + let claims = AuthorizationJwtPayload { + iss: "Chaos".to_string(), + sub: user_id, + jti: Uuid::new_v4(), + aud: vec!["chaos.devsoc.app".to_string()], + exp: expiry, + nbf: i64::try_from(current_time.as_secs()).unwrap(), + iat: i64::try_from(current_time.as_secs()).unwrap(), + username, + }; + + encode(jwt_header, &claims, encoding_key).unwrap() +} + pub fn decode_auth_token( - token: String, + token: &str, decoding_key: &DecodingKey, + jwt_validator: &Validation, ) -> Option { - let decode_token = decode::( - token.as_str(), - decoding_key, - &Validation::new(Algorithm::HS256), - ); + let decode_token = decode::(token, decoding_key, jwt_validator); match decode_token { Ok(token) => Option::from(token.claims), diff --git a/backend/server/src/service/oauth2.rs b/backend/server/src/service/oauth2.rs index 673379fce..43c1104c7 100644 --- a/backend/server/src/service/oauth2.rs +++ b/backend/server/src/service/oauth2.rs @@ -3,12 +3,13 @@ use oauth2::{AuthUrl, ClientId, ClientSecret, RedirectUrl, TokenUrl}; use std::env; /// Returns a oauth2::BasicClient, setup with settings for CHAOS Google OAuth. +/// /// Client follows OAuth2 Standard (https://oauth.net/2/) to get user's email /// using OpenID Connect (https://openid.net/developers/how-connect-works/). pub fn build_oauth_client(client_id: String, client_secret: String) -> BasicClient { let hostname = env::var("CHAOS_HOSTNAME").expect("Could not read CHAOS hostname"); - let redirect_url = format!("{}/api/auth/google_callback", hostname); + let redirect_url = format!("{}/api/auth/callback/google", hostname); let auth_url = AuthUrl::new("https://accounts.google.com/o/oauth2/v2/auth".to_string()) .expect("Invalid authorization endpoint URL"); From 37595e45e063dfc2bd6b87d435431fc6a9aba564 Mon Sep 17 00:00:00 2001 From: Kavika <50282464+KavikaPalletenne@users.noreply.github.com> Date: Sun, 14 Apr 2024 17:44:50 +1000 Subject: [PATCH 23/56] add operationId's to api spec --- backend/api.yaml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/backend/api.yaml b/backend/api.yaml index cb80ef4fa..64be46941 100644 --- a/backend/api.yaml +++ b/backend/api.yaml @@ -11,6 +11,7 @@ servers: paths: /auth/logout: post: + operationId: logout description: Invalidates current token. tags: - Auth @@ -26,6 +27,7 @@ paths: example: Successfully logged out. /user: get: + operationId: getLoggedInUser description: Returns info about currently logged in user. tags: - User @@ -68,6 +70,7 @@ paths: type: string example: Not logged in. delete: + operationId: deleteUserById description: Deletes currently logged in user. tags: - User @@ -101,6 +104,7 @@ paths: example: Not logged in. /user/{id}: get: + operationId: getUserById parameters: - name: id in: path @@ -149,6 +153,7 @@ paths: example: "Insufficient permissions" /user/name: patch: + operationId: updateUserName description: Updates currently logged in user's name. tags: - User @@ -182,6 +187,7 @@ paths: example: Not logged in. /user/zid: patch: + operationId: updateUserZid description: Updates currently logged in user's zID. tags: - User @@ -215,6 +221,7 @@ paths: example: Not logged in. /user/degree: patch: + operationId: updateUserDegree description: Updates currently logged in user's degree. tags: - User @@ -251,6 +258,7 @@ paths: example: Not logged in. /organisation: post: + operationId: createOrganisation description: Creates a new organisation. tags: - Organisation @@ -289,6 +297,7 @@ paths: example: Unauthorized /organisation/{id}: get: + operationId: getOrganisationById parameters: - name: id in: path @@ -321,6 +330,7 @@ paths: type: string example: 2024-02-10T18:25:43.511Z delete: + operationId: deleteOrganisationById parameters: - name: id in: path @@ -353,6 +363,7 @@ paths: example: Unauthorized /organisation/{id}/campaigns: get: + operationId: getOrganisationCampaignsById parameters: - name: id in: path @@ -397,6 +408,7 @@ paths: example: 2024-04-15T18:25:43.511Z /organisation/{id}/logo: patch: + operationId: updateOrganisationLogoById parameters: - name: id in: path @@ -439,6 +451,7 @@ paths: example: Unauthorized /organisation/{id}/members: get: + operationId: getOrganisationMembersById parameters: - name: id in: path @@ -479,6 +492,7 @@ paths: type: string example: Unauthorized put: + operationId: updateOrganisationMembersById parameters: - name: id in: path @@ -533,6 +547,7 @@ paths: example: Unauthorized /organisation/{id}/campaign: post: + operationId: createCampaign parameters: - name: id in: path @@ -583,6 +598,7 @@ paths: example: Unauthorized /campaign: get: + operationId: getAllCampaigns description: Returns all active campaigns. tags: - Campaign @@ -626,6 +642,7 @@ paths: example: 2024-04-15T18:25:43.511Z /campaign/{id}: get: + operationId: getCampaignById parameters: - name: id in: path @@ -671,6 +688,7 @@ paths: type: string example: 2024-04-15T18:25:43.511Z put: + operationId: updateCampaignById parameters: - name: id in: path @@ -729,6 +747,7 @@ paths: type: string example: Unauthorized delete: + operationId: deleteCampaignById parameters: - name: id in: path @@ -761,6 +780,7 @@ paths: example: Unauthorized /campaign/{id}/banner: patch: + operationId: updateCampaignBannerById parameters: - name: id in: path From 84f63246924a5113104bf1de9ee184456316a2a0 Mon Sep 17 00:00:00 2001 From: Kavika <50282464+KavikaPalletenne@users.noreply.github.com> Date: Sun, 14 Apr 2024 17:49:01 +1000 Subject: [PATCH 24/56] Add JSON version of api spec --- backend/api.json | 1292 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1292 insertions(+) create mode 100644 backend/api.json diff --git a/backend/api.json b/backend/api.json new file mode 100644 index 000000000..f070ae821 --- /dev/null +++ b/backend/api.json @@ -0,0 +1,1292 @@ +{ + "openapi": "3.0.0", + "info": { + "title": "Chaos API", + "version": "1.0.0" + }, + "servers": [ + { + "url": "https://chaos.csesoc.app/api", + "description": "Production server" + }, + { + "url": "http://localhost:3000/api", + "description": "Local server" + } + ], + "paths": { + "/auth/logout": { + "post": { + "operationId": "logout", + "description": "Invalidates current token.", + "tags": [ + "Auth" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "messages": { + "type": "string", + "example": "Successfully logged out." + } + } + } + } + } + } + } + } + }, + "/user": { + "get": { + "operationId": "getLoggedInUser", + "description": "Returns info about currently logged in user.", + "tags": [ + "User" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "id": { + "type": "integer", + "format": "int64", + "example": 1541815603606036500 + }, + "email": { + "type": "string", + "example": "me@example.com" + }, + "zid": { + "type": "string", + "example": "z5555555" + }, + "name": { + "type": "string", + "example": "Clancy Lion" + }, + "degree_name": { + "type": "string", + "example": "Computer Science" + }, + "degree_starting_year": { + "type": "integer", + "example": 2024 + }, + "role": { + "type": "string", + "example": "User" + } + } + } + } + } + }, + "401": { + "description": "Not logged in.", + "content": { + "application/json": { + "schema": { + "properties": { + "error": { + "type": "string", + "example": "Not logged in." + } + } + } + } + } + } + } + }, + "delete": { + "operationId": "deleteUserById", + "description": "Deletes currently logged in user.", + "tags": [ + "User" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "message": { + "type": "string", + "example": "Successfully deleted user." + } + } + } + } + } + }, + "401": { + "description": "Not logged.", + "content": { + "application/json": { + "schema": { + "properties": { + "error": { + "type": "string", + "example": "Not logged in." + } + } + } + } + } + }, + "403": { + "description": "User is only admin of an organisation.", + "content": { + "application/json": { + "schema": { + "properties": { + "error": { + "type": "string", + "example": "Cannot delete sole admin of an organisation." + } + } + } + } + } + } + } + } + }, + "/user/{id}": { + "get": { + "operationId": "getUserById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "User ID", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "description": "Returns info about specified user.", + "tags": [ + "User" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "id": { + "type": "integer", + "format": "int64", + "example": 1541815603606036500 + }, + "email": { + "type": "string", + "example": "me@example.com" + }, + "zid": { + "type": "string", + "example": "z5555555" + }, + "name": { + "type": "string", + "example": "Clancy Lion" + }, + "degree_name": { + "type": "string", + "example": "Computer Science" + }, + "degree_starting_year": { + "type": "integer", + "example": 2024 + } + } + } + } + } + }, + "403": { + "description": "Requested user has not applied to one of authorized user's campaign.", + "content": { + "application/json": { + "schema": { + "properties": { + "error": { + "type": "string", + "example": "Insufficient permissions" + } + } + } + } + } + } + } + } + }, + "/user/name": { + "patch": { + "operationId": "updateUserName", + "description": "Updates currently logged in user's name.", + "tags": [ + "User" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "properties": { + "name": { + "type": "string", + "example": "Clancy Tiger" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "message": { + "type": "string", + "example": "Successfully updated name." + } + } + } + } + } + }, + "401": { + "description": "Not logged in.", + "content": { + "application/json": { + "schema": { + "properties": { + "error": { + "type": "string", + "example": "Not logged in." + } + } + } + } + } + } + } + } + }, + "/user/zid": { + "patch": { + "operationId": "updateUserZid", + "description": "Updates currently logged in user's zID.", + "tags": [ + "User" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "properties": { + "zid": { + "type": "string", + "example": "z5123456" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "message": { + "type": "string", + "example": "Successfully updated zID." + } + } + } + } + } + }, + "401": { + "description": "Not logged in.", + "content": { + "application/json": { + "schema": { + "properties": { + "error": { + "type": "string", + "example": "Not logged in." + } + } + } + } + } + } + } + } + }, + "/user/degree": { + "patch": { + "operationId": "updateUserDegree", + "description": "Updates currently logged in user's degree.", + "tags": [ + "User" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "properties": { + "degree_name": { + "type": "string", + "example": "Electrical Engineering" + }, + "degree_starting_year": { + "type": "integer", + "example": 2024 + } + } + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "message": { + "type": "string", + "example": "Successfully updated email." + } + } + } + } + } + }, + "401": { + "description": "Not logged in.", + "content": { + "application/json": { + "schema": { + "properties": { + "error": { + "type": "string", + "example": "Not logged in." + } + } + } + } + } + } + } + } + }, + "/organisation": { + "post": { + "operationId": "createOrganisation", + "description": "Creates a new organisation.", + "tags": [ + "Organisation" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "properties": { + "name": { + "type": "string", + "example": "UNSW Software Development Society" + }, + "admin": { + "type": "integer", + "format": "int64", + "example": 1541815603606036500, + "description": "User ID of admin" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "message": { + "type": "string", + "example": "Successfully created organisation." + } + } + } + } + } + }, + "403": { + "description": "User is not a super user.", + "content": { + "application/json": { + "schema": { + "properties": { + "error": { + "type": "string", + "example": "Unauthorized" + } + } + } + } + } + } + } + } + }, + "/organisation/{id}": { + "get": { + "operationId": "getOrganisationById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "Organisation ID", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "description": "Returns info about specified organisation.", + "tags": [ + "Organisation" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "id": { + "type": "integer", + "format": "int64", + "example": 6996987893965263000 + }, + "name": { + "type": "string", + "example": "UNSW Software Development Society" + }, + "logo": { + "type": "string", + "example": "76718252-2a13-4de2-bc07-f977c75dc52b" + }, + "created_at": { + "type": "string", + "example": "2024-02-10T18:25:43.511Z" + } + } + } + } + } + } + } + }, + "delete": { + "operationId": "deleteOrganisationById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "Organisation ID", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "description": "Deletes specified organisation.", + "tags": [ + "Organisation" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "message": { + "type": "string", + "example": "Successfully deleted organisation." + } + } + } + } + } + }, + "403": { + "description": "User is not a super user.", + "content": { + "application/json": { + "schema": { + "properties": { + "error": { + "type": "string", + "example": "Unauthorized" + } + } + } + } + } + } + } + } + }, + "/organisation/{id}/campaigns": { + "get": { + "operationId": "getOrganisationCampaignsById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "Organisation ID", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "description": "Returns active campaigns for specified organisation.", + "tags": [ + "Organisation" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "campaigns": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "example": 6996987893965263000 + }, + "name": { + "type": "string", + "example": "2024 Subcommittee Recruitment" + }, + "cover_image": { + "type": "string", + "example": "2d19617b-46fd-4927-9f53-77d69232ba5d" + }, + "description": { + "type": "string", + "example": "Are you excited to make a difference?" + }, + "starts_at": { + "type": "string", + "example": "2024-03-15T18:25:43.511Z" + }, + "ends_at": { + "type": "string", + "example": "2024-04-15T18:25:43.511Z" + } + } + } + } + } + } + } + } + } + } + } + }, + "/organisation/{id}/logo": { + "patch": { + "operationId": "updateOrganisationLogoById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "Organisation ID", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "description": "Updates logo for specified organistion.", + "tags": [ + "Organisation" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "upload_url": { + "type": "string", + "description": "Presigned S3 url to upload file.", + "example": "https://presignedurldemo.s3.eu-west-2.amazonaws.com/6996987893965262849/2d19617b-46fd-4927-9f53-77d69232ba5d?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJJWZ7B6WCRGMKFGQ%2F20180210%2Feu-west-2%2Fs3%2Faws4_request&X-Amz-Date=20180210T171315Z&X-Amz-Expires=1800&X-Amz-Signature=12b74b0788aa036bc7c3d03b3f20c61f1f91cc9ad8873e3314255dc479a25351&X-Amz-SignedHeaders=host" + } + } + } + } + } + }, + "401": { + "description": "Not logged in.", + "content": { + "application/json": { + "schema": { + "properties": { + "error": { + "type": "string", + "example": "Not logged in." + } + } + } + } + } + }, + "403": { + "description": "User is not an organisation admin.", + "content": { + "application/json": { + "schema": { + "properties": { + "error": { + "type": "string", + "example": "Unauthorized" + } + } + } + } + } + } + } + } + }, + "/organisation/{id}/members": { + "get": { + "operationId": "getOrganisationMembersById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "Organisation ID", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "description": "Returns list of members of specified organisation.", + "tags": [ + "Organisation" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "members": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "example": 1541815603606036500 + }, + "name": { + "type": "string", + "example": "Clancy Lion" + } + } + } + } + } + } + } + } + }, + "403": { + "description": "User is not an organisation admin or member.", + "content": { + "application/json": { + "schema": { + "properties": { + "error": { + "type": "string", + "example": "Unauthorized" + } + } + } + } + } + } + } + }, + "put": { + "operationId": "updateOrganisationMembersById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "Organisation ID", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "properties": { + "members": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "integer", + "format": "int64" + }, + "example": [ + 1541815603606036500, + 1541815603606036700, + 1541815287306036500 + ] + } + } + } + } + } + }, + "description": "Specifies members for specified organistion.", + "tags": [ + "Organisation" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "message": { + "type": "string", + "example": "Successfully updated members." + } + } + } + } + } + }, + "401": { + "description": "Not logged in.", + "content": { + "application/json": { + "schema": { + "properties": { + "error": { + "type": "string", + "example": "Not logged in." + } + } + } + } + } + }, + "403": { + "description": "User is not an organisation admin.", + "content": { + "application/json": { + "schema": { + "properties": { + "error": { + "type": "string", + "example": "Unauthorized" + } + } + } + } + } + } + } + } + }, + "/organisation/{id}/campaign": { + "post": { + "operationId": "createCampaign", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "Organisation ID", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "description": "Creates a new campaign inside specified organisation.", + "tags": [ + "Organisation" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "properties": { + "name": { + "type": "string", + "example": "2024 Subcommittee Recruitment" + }, + "description": { + "type": "string", + "example": "Are you excited to make a difference?" + }, + "starts_at": { + "type": "string", + "example": "2024-03-15T18:25:43.511Z" + }, + "ends_at": { + "type": "string", + "example": "2024-04-15T18:25:43.511Z" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "message": { + "type": "string", + "example": "Successfully created campaign." + } + } + } + } + } + }, + "403": { + "description": "User is not an admin of specified organisation.", + "content": { + "application/json": { + "schema": { + "properties": { + "error": { + "type": "string", + "example": "Unauthorized" + } + } + } + } + } + } + } + } + }, + "/campaign": { + "get": { + "operationId": "getAllCampaigns", + "description": "Returns all active campaigns.", + "tags": [ + "Campaign" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "campaigns": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "example": 6996987893965263000 + }, + "organisation_id": { + "type": "integer", + "format": "int64", + "example": 1541815603606036700 + }, + "organisation_name": { + "type": "string", + "example": "UNSW Software Development Society" + }, + "name": { + "type": "string", + "example": "2024 Subcommittee Recruitment" + }, + "cover_image": { + "type": "string", + "example": "2d19617b-46fd-4927-9f53-77d69232ba5d" + }, + "description": { + "type": "string", + "example": "Are you excited to make a difference?" + }, + "starts_at": { + "type": "string", + "example": "2024-03-15T18:25:43.511Z" + }, + "ends_at": { + "type": "string", + "example": "2024-04-15T18:25:43.511Z" + } + } + } + } + } + } + } + } + } + } + } + }, + "/campaign/{id}": { + "get": { + "operationId": "getCampaignById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "Campaign ID", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "description": "Returns info about specified campaign.", + "tags": [ + "Campaign" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "id": { + "type": "integer", + "format": "int64", + "example": 6996987893965263000 + }, + "organisation_id": { + "type": "integer", + "format": "int64", + "example": 1541815603606036700 + }, + "organisation_name": { + "type": "string", + "example": "UNSW Software Development Society" + }, + "name": { + "type": "string", + "example": "2024 Subcommittee Recruitment" + }, + "cover_image": { + "type": "string", + "example": "2d19617b-46fd-4927-9f53-77d69232ba5d" + }, + "description": { + "type": "string", + "example": "Are you excited to make a difference?" + }, + "starts_at": { + "type": "string", + "example": "2024-03-15T18:25:43.511Z" + }, + "ends_at": { + "type": "string", + "example": "2024-04-15T18:25:43.511Z" + } + } + } + } + } + } + } + }, + "put": { + "operationId": "updateCampaignById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "Campaign ID", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "properties": { + "name": { + "type": "string", + "example": "2024 Subcommittee Recruitment" + }, + "description": { + "type": "string", + "example": "Are you excited to make a difference?" + }, + "starts_at": { + "type": "string", + "example": "2024-03-15T18:25:43.511Z" + }, + "ends_at": { + "type": "string", + "example": "2024-04-15T18:25:43.511Z" + } + } + } + } + } + }, + "description": "Updates details of specified campaign.", + "tags": [ + "Campaign" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "message": { + "type": "string", + "example": "Successfully updated campaign." + } + } + } + } + } + }, + "401": { + "description": "Not logged in.", + "content": { + "application/json": { + "schema": { + "properties": { + "error": { + "type": "string", + "example": "Not logged in." + } + } + } + } + } + }, + "403": { + "description": "User is not an organisation admin.", + "content": { + "application/json": { + "schema": { + "properties": { + "error": { + "type": "string", + "example": "Unauthorized" + } + } + } + } + } + } + } + }, + "delete": { + "operationId": "deleteCampaignById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "Campaign ID", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "description": "Deletes specified campaign.", + "tags": [ + "Campaign" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "message": { + "type": "string", + "example": "Successfully deleted campaign." + } + } + } + } + } + }, + "403": { + "description": "User is not an admin of campaign's organisation.", + "content": { + "application/json": { + "schema": { + "properties": { + "error": { + "type": "string", + "example": "Unauthorized" + } + } + } + } + } + } + } + } + }, + "/campaign/{id}/banner": { + "patch": { + "operationId": "updateCampaignBannerById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "Campaign ID", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "description": "Updates banner image for specified campaign.", + "tags": [ + "Campaign" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "upload_url": { + "type": "string", + "description": "Presigned S3 url to upload file.", + "example": "https://presignedurldemo.s3.eu-west-2.amazonaws.com/6996987893965262849/2d19617b-46fd-4927-9f53-77d69232ba5d?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJJWZ7B6WCRGMKFGQ%2F20180210%2Feu-west-2%2Fs3%2Faws4_request&X-Amz-Date=20180210T171315Z&X-Amz-Expires=1800&X-Amz-Signature=12b74b0788aa036bc7c3d03b3f20c61f1f91cc9ad8873e3314255dc479a25351&X-Amz-SignedHeaders=host" + } + } + } + } + } + }, + "401": { + "description": "Not logged in.", + "content": { + "application/json": { + "schema": { + "properties": { + "error": { + "type": "string", + "example": "Not logged in." + } + } + } + } + } + }, + "403": { + "description": "User is not an organisation admin.", + "content": { + "application/json": { + "schema": { + "properties": { + "error": { + "type": "string", + "example": "Unauthorized" + } + } + } + } + } + } + } + } + } + } + } \ No newline at end of file From 1405e9726a5459b4c1a74790ba329785c615b8b9 Mon Sep 17 00:00:00 2001 From: Kavika Date: Fri, 28 Jun 2024 16:31:48 +1000 Subject: [PATCH 25/56] Error handling with `thiserror` (#494) * feat(db): add indexes for foreign key reference columns * fix(db): index naming and missing semicolons * dep(backend): update axum * fix(backend): remove testing jwt handlers * feat(backend): Add custom jwt validator and header * feat(backend): basic error handling enum * fix(backend): ran cargo fmt * fix(backend): remove unused imports * Change to using `thiserror` * remove 'Error' from logic error names --- backend/server/Cargo.toml | 1 + backend/server/src/models/auth.rs | 3 ++- backend/server/src/models/error.rs | 35 ++++++++++++++++++++---------- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/backend/server/Cargo.toml b/backend/server/Cargo.toml index fd7647485..84445fdc7 100644 --- a/backend/server/Cargo.toml +++ b/backend/server/Cargo.toml @@ -14,6 +14,7 @@ sqlx = { version = "0.7", features = ["runtime-tokio-rustls", "postgres", "time" # Important secondary crates anyhow = "1.0" +thiserror = "1.0" serde = { version = "1.0", features = ["derive"] } reqwest = { version = "0.11", features = ["json"] } serde_json = "1.0" diff --git a/backend/server/src/models/auth.rs b/backend/server/src/models/auth.rs index 149c3a25b..c292f092c 100644 --- a/backend/server/src/models/auth.rs +++ b/backend/server/src/models/auth.rs @@ -91,6 +91,7 @@ where let claims = decode_auth_token(token, decoding_key, jwt_validator).ok_or(ChaosError::NotLoggedIn)?; + let pool = &app_state.db; let possible_user = is_super_user(claims.sub, pool).await; @@ -102,6 +103,6 @@ where } } - Err(ChaosError::NotLoggedIn) + Err(ChaosError::Unauthorized) } } diff --git a/backend/server/src/models/error.rs b/backend/server/src/models/error.rs index ca160d978..86c3004cd 100644 --- a/backend/server/src/models/error.rs +++ b/backend/server/src/models/error.rs @@ -3,31 +3,42 @@ use axum::response::{IntoResponse, Redirect, Response}; /// Custom error enum for Chaos. /// -/// Handles all anyhow errors (when `?` is used) alongside +/// Handles all errors thrown by libraries (when `?` is used) alongside /// specific errors for business logic. +#[derive(thiserror::Error, Debug)] pub enum ChaosError { + #[error("Not logged in")] NotLoggedIn, + + #[error("Not authorized")] Unauthorized, + + #[error("Forbidden operation")] ForbiddenOperation, - ServerError(anyhow::Error), + + #[error("SQLx error")] + DatabaseError(#[from] sqlx::Error), + + #[error("Reqwest error")] + ReqwestError(#[from] reqwest::Error), + + #[error("OAuth2 error")] + OAuthError(#[from] oauth2::RequestTokenError, oauth2::StandardErrorResponse>) } +/// Implementation for converting errors into responses. Manages error code and message returned. impl IntoResponse for ChaosError { fn into_response(self) -> Response { match self { ChaosError::NotLoggedIn => Redirect::temporary("/auth/google").into_response(), ChaosError::Unauthorized => (StatusCode::UNAUTHORIZED, "Unauthorized").into_response(), ChaosError::ForbiddenOperation => (StatusCode::FORBIDDEN, "Forbidden operation").into_response(), - ChaosError::ServerError(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()).into_response() + ChaosError::DatabaseError(db_error) => match db_error { + // We only care about the RowNotFound error, as others are miscellaneous DB errors. + sqlx::Error::RowNotFound => (StatusCode::NOT_FOUND, "Not found").into_response(), + _ => (StatusCode::INTERNAL_SERVER_ERROR, "Internal server error").into_response(), + }, + _ => (StatusCode::INTERNAL_SERVER_ERROR, "Internal server error").into_response() } } } - -impl From for ChaosError -where - E: Into, -{ - fn from(err: E) -> Self { - ChaosError::ServerError(err.into()) - } -} From 5fe7adda70ffcce6dfb85479397726e3f2a62fdc Mon Sep 17 00:00:00 2001 From: alexlai18 <104405034+alexlai18@users.noreply.github.com> Date: Fri, 28 Jun 2024 17:44:07 +1000 Subject: [PATCH 26/56] Organisations CRUD (#485) * feat: Initial draft TODO: TESTING + more clarification * rearranged import * clear errors * post testing * feat(db): add indexes for foreign key reference columns * fix(db): index naming and missing semicolons * dep(backend): update axum * fix(backend): remove testing jwt handlers * feat(backend): Add custom jwt validator and header * feat(backend): basic error handling enum * fix(backend): ran cargo fmt * fix(backend): remove unused imports * CRUD operations - awaiting Campaign - haven't enforced db safety * implement feedback * Update rust.yml to include 224 branch * logic and style fixes * Change to using `thiserror` * add organisation_role type to db * update migration timestamps to be `NOT NULL` * change sqlx `time` to `chrono` * integrate organisations crud with error handling * return member role with org members * update sqlx type name for `UserRole` * simplify handlers to use new error type * removed unused imports * added `OrganisationAdmin` extractor * use `Transaction` when doing multiple queries * cargo fmt * add org route to app * move `Organisation` service functions into `Organisation` struct * moved org handlers into `OrganisationHandler` struct * ran cargo fmt * add S3 url generation to logo update * fixed error renaming * add routes to `main.rs` * cargo fmt --------- Co-authored-by: Alexander Co-authored-by: Kavika --- backend/api.json | 4 + backend/api.yaml | 3 + .../20240406023149_create_users.sql | 4 +- .../20240406024211_create_organisations.sql | 13 +- .../20240406025537_create_campaigns.sql | 8 +- .../20240406031400_create_questions.sql | 4 +- .../20240406031915_create_applications.sql | 8 +- backend/server/Cargo.toml | 4 +- backend/server/src/handler/mod.rs | 1 + backend/server/src/handler/organisation.rs | 160 ++++++++ backend/server/src/main.rs | 36 +- backend/server/src/models/app.rs | 2 + backend/server/src/models/auth.rs | 48 ++- backend/server/src/models/campaign.rs | 12 + backend/server/src/models/error.rs | 21 +- backend/server/src/models/mod.rs | 4 + backend/server/src/models/organisation.rs | 345 ++++++++++++++++++ backend/server/src/models/storage.rs | 54 +++ backend/server/src/models/transaction.rs | 27 ++ backend/server/src/models/user.rs | 2 +- backend/server/src/service/auth.rs | 2 +- backend/server/src/service/jwt.rs | 2 +- backend/server/src/service/mod.rs | 1 + backend/server/src/service/organisation.rs | 28 ++ 24 files changed, 762 insertions(+), 31 deletions(-) create mode 100644 backend/server/src/handler/organisation.rs create mode 100644 backend/server/src/models/campaign.rs create mode 100644 backend/server/src/models/organisation.rs create mode 100644 backend/server/src/models/storage.rs create mode 100644 backend/server/src/models/transaction.rs create mode 100644 backend/server/src/service/organisation.rs diff --git a/backend/api.json b/backend/api.json index f070ae821..8be962fe5 100644 --- a/backend/api.json +++ b/backend/api.json @@ -746,6 +746,10 @@ "name": { "type": "string", "example": "Clancy Lion" + }, + "role": { + "type": "string", + "example": "Admin" } } } diff --git a/backend/api.yaml b/backend/api.yaml index 64be46941..0456733a6 100644 --- a/backend/api.yaml +++ b/backend/api.yaml @@ -482,6 +482,9 @@ paths: name: type: string example: Clancy Lion + role: + type: string + example: Admin '403': description: User is not an organisation admin or member. content: diff --git a/backend/migrations/20240406023149_create_users.sql b/backend/migrations/20240406023149_create_users.sql index 0bb4cd8b3..f862c0da2 100644 --- a/backend/migrations/20240406023149_create_users.sql +++ b/backend/migrations/20240406023149_create_users.sql @@ -8,8 +8,8 @@ CREATE TABLE users ( degree_name TEXT, degree_starting_year INTEGER, role user_role NOT NULL, - created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP + created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL, + updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL ); CREATE UNIQUE INDEX IDX_users_email_lower on users ((lower(email))); diff --git a/backend/migrations/20240406024211_create_organisations.sql b/backend/migrations/20240406024211_create_organisations.sql index 88dda366d..2e9c8bf77 100644 --- a/backend/migrations/20240406024211_create_organisations.sql +++ b/backend/migrations/20240406024211_create_organisations.sql @@ -2,19 +2,22 @@ CREATE TABLE organisations ( id BIGINT PRIMARY KEY, name TEXT NOT NULL UNIQUE, logo TEXT, - created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP + created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL, + updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL ); -CREATE TABLE organisation_admins ( +CREATE TYPE organisation_role AS ENUM ('User', 'Admin'); + +CREATE TABLE organisation_members ( id SERIAL PRIMARY KEY, organisation_id BIGINT NOT NULL, user_id BIGINT NOT NULL, - CONSTRAINT FK_organisation_admins_organisation + role organisation_role DEFAULT 'User' NOT NULL, + CONSTRAINT FK_organisation_members_organisation FOREIGN KEY(organisation_id) REFERENCES organisations(id) ON DELETE CASCADE ON UPDATE CASCADE ); -CREATE INDEX IDX_organisation_admins_organisation on organisation_admins (organisation_id); +CREATE INDEX IDX_organisation_admins_organisation on organisation_members (organisation_id); diff --git a/backend/migrations/20240406025537_create_campaigns.sql b/backend/migrations/20240406025537_create_campaigns.sql index 46bca9df2..c49df429a 100644 --- a/backend/migrations/20240406025537_create_campaigns.sql +++ b/backend/migrations/20240406025537_create_campaigns.sql @@ -6,8 +6,8 @@ CREATE TABLE campaigns ( description TEXT, starts_at TIMESTAMPTZ NOT NULL, ends_at TIMESTAMPTZ NOT NULL, - created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, + created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL, + updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL, CONSTRAINT FK_campaigns_organisations FOREIGN KEY(organisation_id) REFERENCES organisations(id) @@ -23,8 +23,8 @@ CREATE TABLE campaign_roles ( min_available INTEGER, max_available INTEGER, finalised BOOLEAN, - created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, + created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL, + updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL, CONSTRAINT FK_campaign_roles_campaign FOREIGN KEY(campaign_id) REFERENCES campaigns(id) diff --git a/backend/migrations/20240406031400_create_questions.sql b/backend/migrations/20240406031400_create_questions.sql index fa1708132..050d07fef 100644 --- a/backend/migrations/20240406031400_create_questions.sql +++ b/backend/migrations/20240406031400_create_questions.sql @@ -7,8 +7,8 @@ CREATE TABLE questions ( required BOOLEAN, question_type question_type NOT NULL, campaign_id BIGINT NOT NULL, - created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, + created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL, + updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL, CONSTRAINT FK_questions_campaigns FOREIGN KEY(campaign_id) REFERENCES campaigns(id) diff --git a/backend/migrations/20240406031915_create_applications.sql b/backend/migrations/20240406031915_create_applications.sql index 91d9edcf4..767abb92a 100644 --- a/backend/migrations/20240406031915_create_applications.sql +++ b/backend/migrations/20240406031915_create_applications.sql @@ -6,8 +6,8 @@ CREATE TABLE applications ( user_id BIGINT NOT NULL, status application_status NOT NULL, private_status application_status NOT NULL, - created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, + created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL, + updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL, CONSTRAINT FK_applications_campaigns FOREIGN KEY(campaign_id) REFERENCES campaigns(id) @@ -95,8 +95,8 @@ CREATE TABLE application_ratings ( application_id BIGINT NOT NULL, rater_id BIGINT NOT NULL, rating INTEGER NOT NULL, - created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, + created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL, + updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL, CONSTRAINT FK_application_ratings_applications FOREIGN KEY(application_id) REFERENCES applications(id) diff --git a/backend/server/Cargo.toml b/backend/server/Cargo.toml index 84445fdc7..9c4babe2f 100644 --- a/backend/server/Cargo.toml +++ b/backend/server/Cargo.toml @@ -10,7 +10,7 @@ edition = "2021" tokio = { version = "1.34", features = ["macros", "rt-multi-thread"] } axum = { version = "0.7", features = ["macros"] } axum-extra = { version = "0.9", features = ["typed-header"] } -sqlx = { version = "0.7", features = ["runtime-tokio-rustls", "postgres", "time", "uuid"] } +sqlx = { version = "0.7", features = ["runtime-tokio-rustls", "postgres", "chrono", "uuid"] } # Important secondary crates anyhow = "1.0" @@ -22,6 +22,8 @@ chrono = { version = "0.4", features = ["serde"] } oauth2 = "4.4" log = "0.4" uuid = { version = "1.5", features = ["serde", "v4"] } +rust-s3 = "0.34.0" rs-snowflake = "0.6" jsonwebtoken = "9.1" dotenvy = "0.15" + diff --git a/backend/server/src/handler/mod.rs b/backend/server/src/handler/mod.rs index 0e4a05d59..163c47590 100644 --- a/backend/server/src/handler/mod.rs +++ b/backend/server/src/handler/mod.rs @@ -1 +1,2 @@ pub mod auth; +pub mod organisation; diff --git a/backend/server/src/handler/organisation.rs b/backend/server/src/handler/organisation.rs new file mode 100644 index 000000000..e1f08100b --- /dev/null +++ b/backend/server/src/handler/organisation.rs @@ -0,0 +1,160 @@ +use crate::models; +use crate::models::app::AppState; +use crate::models::auth::SuperUser; +use crate::models::auth::{AuthUser, OrganisationAdmin}; +use crate::models::error::ChaosError; +use crate::models::organisation::{AdminToRemove, AdminUpdateList, NewOrganisation, Organisation}; +use crate::models::transaction::DBTransaction; +use crate::service; +use axum::extract::{Json, Path, State}; +use axum::http::StatusCode; +use axum::response::IntoResponse; + +pub struct OrganisationHandler; + +impl OrganisationHandler { + pub async fn create( + State(state): State, + _user: SuperUser, + mut transaction: DBTransaction<'_>, + Json(data): Json, + ) -> Result { + Organisation::create( + data.admin, + data.name, + state.snowflake_generator, + &mut transaction.tx, + ) + .await?; + + transaction.tx.commit().await?; + Ok((StatusCode::OK, "Successfully created organisation")) + } + + pub async fn get( + State(state): State, + Path(id): Path, + _user: AuthUser, + ) -> Result { + let org = Organisation::get(id, &state.db).await?; + Ok((StatusCode::OK, Json(org))) + } + + pub async fn delete( + State(state): State, + Path(id): Path, + _user: SuperUser, + ) -> Result { + Organisation::delete(id, &state.db).await?; + Ok((StatusCode::OK, "Successfully deleted organisation")) + } + + pub async fn get_admins( + State(state): State, + Path(id): Path, + _user: SuperUser, + ) -> Result { + let members = Organisation::get_admins(id, &state.db).await?; + Ok((StatusCode::OK, Json(members))) + } + + pub async fn get_members( + State(state): State, + Path(id): Path, + _admin: OrganisationAdmin, + ) -> Result { + let members = Organisation::get_members(id, &state.db).await?; + Ok((StatusCode::OK, Json(members))) + } + + pub async fn update_admins( + State(state): State, + Path(id): Path, + _super_user: SuperUser, + mut transaction: DBTransaction<'_>, + Json(request_body): Json, + ) -> Result { + Organisation::update_admins(id, request_body.members, &mut transaction.tx).await?; + + transaction.tx.commit().await?; + Ok((StatusCode::OK, "Successfully updated organisation members")) + } + + pub async fn update_members( + State(state): State, + mut transaction: DBTransaction<'_>, + Path(id): Path, + _admin: OrganisationAdmin, + Json(request_body): Json, + ) -> Result { + Organisation::update_members(id, request_body.members, &mut transaction.tx).await?; + + transaction.tx.commit().await?; + Ok((StatusCode::OK, "Successfully updated organisation members")) + } + + pub async fn remove_admin( + State(state): State, + Path(id): Path, + _super_user: SuperUser, + Json(request_body): Json, + ) -> Result { + Organisation::remove_admin(id, request_body.user_id, &state.db).await?; + + Ok(( + StatusCode::OK, + "Successfully removed member from organisation", + )) + } + + pub async fn remove_member( + State(state): State, + Path(id): Path, + _admin: OrganisationAdmin, + Json(request_body): Json, + ) -> Result { + Organisation::remove_member(id, request_body.user_id, &state.db).await?; + + Ok(( + StatusCode::OK, + "Successfully removed member from organisation", + )) + } + + pub async fn update_logo( + State(state): State, + Path(id): Path, + _admin: OrganisationAdmin, + ) -> Result { + let logo_url = Organisation::update_logo(id, &state.db, &state.storage_bucket).await?; + Ok((StatusCode::OK, Json(logo_url))) + } + + pub async fn get_campaigns( + State(state): State, + Path(id): Path, + _user: AuthUser, + ) -> Result { + let campaigns = Organisation::get_campaigns(id, &state.db).await?; + + Ok((StatusCode::OK, Json(campaigns))) + } + + pub async fn create_campaign( + State(mut state): State, + _admin: OrganisationAdmin, + Json(request_body): Json, + ) -> Result { + Organisation::create_campaign( + request_body.name, + request_body.description, + request_body.starts_at, + request_body.ends_at, + &state.db, + &mut state.snowflake_generator, + ) + .await?; + + Ok((StatusCode::OK, "Successfully created campaign")) + } +} diff --git a/backend/server/src/main.rs b/backend/server/src/main.rs index 8d91e4b04..38b2022c9 100644 --- a/backend/server/src/main.rs +++ b/backend/server/src/main.rs @@ -1,11 +1,14 @@ +use crate::handler::auth::google_callback; +use crate::handler::organisation::OrganisationHandler; +use crate::models::storage::Storage; use anyhow::Result; -use axum::{routing::get, Router}; +use axum::routing::{get, patch, post, put}; +use axum::Router; use jsonwebtoken::{Algorithm, DecodingKey, EncodingKey, Header, Validation}; use models::app::AppState; use snowflake::SnowflakeIdGenerator; use sqlx::postgres::PgPoolOptions; use std::env; -use crate::handler::auth::google_callback; mod handler; mod models; @@ -43,6 +46,9 @@ async fn main() -> Result<()> { // Initialise Snowflake Generator let snowflake_generator = SnowflakeIdGenerator::new(1, 1); + // Initialise S3 bucket + let storage_bucket = Storage::init_bucket(); + // Add all data to AppState let state = AppState { db: pool, @@ -52,11 +58,37 @@ async fn main() -> Result<()> { jwt_header, jwt_validator, snowflake_generator, + storage_bucket, }; let app = Router::new() .route("/", get(|| async { "Hello, World!" })) .route("/api/auth/callback/google", get(google_callback)) + .route("/api/v1/organisation", post(OrganisationHandler::create)) + .route( + "/api/v1/organisation/:id", + get(OrganisationHandler::get).delete(OrganisationHandler::delete), + ) + .route( + "/api/v1/organisation/:id/campaign", + get(OrganisationHandler::get_campaigns).post(OrganisationHandler::create_campaign), + ) + .route( + "/api/v1/organisation/:id/logo", + patch(OrganisationHandler::update_logo), + ) + .route( + "/api/v1/organisation/:id/member", + get(OrganisationHandler::get_members) + .put(OrganisationHandler::update_members) + .delete(OrganisationHandler::remove_member), + ) + .route( + "/api/v1/organisation/:id/admin", + get(OrganisationHandler::get_admins) + .put(OrganisationHandler::update_admins) + .delete(OrganisationHandler::remove_admin), + ) .with_state(state); let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); diff --git a/backend/server/src/models/app.rs b/backend/server/src/models/app.rs index 9fbd2a8e8..19ecfbffa 100644 --- a/backend/server/src/models/app.rs +++ b/backend/server/src/models/app.rs @@ -1,5 +1,6 @@ use jsonwebtoken::{DecodingKey, EncodingKey, Header, Validation}; use reqwest::Client as ReqwestClient; +use s3::Bucket; use snowflake::SnowflakeIdGenerator; use sqlx::{Pool, Postgres}; @@ -12,4 +13,5 @@ pub struct AppState { pub jwt_header: Header, pub jwt_validator: Validation, pub snowflake_generator: SnowflakeIdGenerator, + pub storage_bucket: Bucket, } diff --git a/backend/server/src/models/auth.rs b/backend/server/src/models/auth.rs index c292f092c..b5e9c2980 100644 --- a/backend/server/src/models/auth.rs +++ b/backend/server/src/models/auth.rs @@ -2,13 +2,11 @@ use crate::models::app::AppState; use crate::models::error::ChaosError; use crate::service::auth::is_super_user; use crate::service::jwt::decode_auth_token; -use axum::extract::{FromRef, FromRequestParts}; +use crate::service::organisation::user_is_admin; +use axum::extract::{FromRef, FromRequestParts, Path}; use axum::http::request::Parts; use axum::response::{IntoResponse, Redirect, Response}; -use axum::{ - async_trait, - RequestPartsExt, -}; +use axum::{async_trait, RequestPartsExt}; use axum_extra::{headers::Cookie, TypedHeader}; use serde::{Deserialize, Serialize}; @@ -106,3 +104,43 @@ where Err(ChaosError::Unauthorized) } } + +pub struct OrganisationAdmin { + pub user_id: i64, +} + +#[async_trait] +impl FromRequestParts for OrganisationAdmin +where + AppState: FromRef, + S: Send + Sync, +{ + type Rejection = ChaosError; + + async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { + let app_state = AppState::from_ref(state); + let decoding_key = &app_state.decoding_key; + let jwt_validator = &app_state.jwt_validator; + let TypedHeader(cookies) = parts + .extract::>() + .await + .map_err(|_| ChaosError::NotLoggedIn)?; + + let token = cookies.get("auth_token").ok_or(ChaosError::NotLoggedIn)?; + + let claims = + decode_auth_token(token, decoding_key, jwt_validator).ok_or(ChaosError::NotLoggedIn)?; + + let pool = &app_state.db; + let user_id = claims.sub; + + let Path(organisation_id) = parts + .extract::>() + .await + .map_err(|_| ChaosError::BadRequest)?; + + user_is_admin(user_id, organisation_id, pool).await?; + + Ok(OrganisationAdmin { user_id }) + } +} diff --git a/backend/server/src/models/campaign.rs b/backend/server/src/models/campaign.rs new file mode 100644 index 000000000..a139900c1 --- /dev/null +++ b/backend/server/src/models/campaign.rs @@ -0,0 +1,12 @@ +use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; + +#[derive(Deserialize, Serialize, Clone, Debug)] +pub struct Campaign { + pub id: i64, + pub name: String, + pub description: Option, + pub cover_image: Option, + pub starts_at: DateTime, + pub ends_at: DateTime, +} diff --git a/backend/server/src/models/error.rs b/backend/server/src/models/error.rs index 86c3004cd..3a2869e3d 100644 --- a/backend/server/src/models/error.rs +++ b/backend/server/src/models/error.rs @@ -16,6 +16,9 @@ pub enum ChaosError { #[error("Forbidden operation")] ForbiddenOperation, + #[error("Bad request")] + BadRequest, + #[error("SQLx error")] DatabaseError(#[from] sqlx::Error), @@ -23,7 +26,16 @@ pub enum ChaosError { ReqwestError(#[from] reqwest::Error), #[error("OAuth2 error")] - OAuthError(#[from] oauth2::RequestTokenError, oauth2::StandardErrorResponse>) + OAuthError( + #[from] + oauth2::RequestTokenError< + oauth2::reqwest::Error, + oauth2::StandardErrorResponse, + >, + ), + + #[error("S3 error")] + StorageError(#[from] s3::error::S3Error), } /// Implementation for converting errors into responses. Manages error code and message returned. @@ -32,13 +44,16 @@ impl IntoResponse for ChaosError { match self { ChaosError::NotLoggedIn => Redirect::temporary("/auth/google").into_response(), ChaosError::Unauthorized => (StatusCode::UNAUTHORIZED, "Unauthorized").into_response(), - ChaosError::ForbiddenOperation => (StatusCode::FORBIDDEN, "Forbidden operation").into_response(), + ChaosError::ForbiddenOperation => { + (StatusCode::FORBIDDEN, "Forbidden operation").into_response() + } + ChaosError::BadRequest => (StatusCode::BAD_REQUEST, "Bad request").into_response(), ChaosError::DatabaseError(db_error) => match db_error { // We only care about the RowNotFound error, as others are miscellaneous DB errors. sqlx::Error::RowNotFound => (StatusCode::NOT_FOUND, "Not found").into_response(), _ => (StatusCode::INTERNAL_SERVER_ERROR, "Internal server error").into_response(), }, - _ => (StatusCode::INTERNAL_SERVER_ERROR, "Internal server error").into_response() + _ => (StatusCode::INTERNAL_SERVER_ERROR, "Internal server error").into_response(), } } } diff --git a/backend/server/src/models/mod.rs b/backend/server/src/models/mod.rs index b992e0f91..e5a5edb3d 100644 --- a/backend/server/src/models/mod.rs +++ b/backend/server/src/models/mod.rs @@ -1,4 +1,8 @@ pub mod app; pub mod auth; +pub mod campaign; pub mod error; +pub mod organisation; +pub mod storage; +pub mod transaction; pub mod user; diff --git a/backend/server/src/models/organisation.rs b/backend/server/src/models/organisation.rs new file mode 100644 index 000000000..d21bd50d7 --- /dev/null +++ b/backend/server/src/models/organisation.rs @@ -0,0 +1,345 @@ +use crate::models::campaign::Campaign; +use crate::models::error::ChaosError; +use crate::models::storage::Storage; +use chrono::{DateTime, Utc}; +use s3::Bucket; +use serde::{Deserialize, Serialize}; +use snowflake::SnowflakeIdGenerator; +use sqlx::{FromRow, Pool, Postgres, Transaction}; +use std::ops::DerefMut; +use uuid::Uuid; + +#[derive(Deserialize, Serialize, Clone, FromRow, Debug)] +pub struct Organisation { + pub id: i64, + pub name: String, + pub logo: Option, + pub created_at: DateTime, + pub updated_at: DateTime, + pub campaigns: Vec, // Awaiting Campaign to be complete - remove comment once done + pub organisation_admins: Vec, +} + +#[derive(Deserialize, Serialize)] +pub struct NewOrganisation { + pub name: String, + pub admin: i64, +} + +#[derive(Deserialize, Serialize)] +pub struct OrganisationDetails { + pub id: i64, + pub name: String, + pub logo: Option, + pub created_at: DateTime, +} + +#[derive(Deserialize, Serialize, sqlx::Type, Clone)] +#[sqlx(type_name = "organisation_role", rename_all = "PascalCase")] +pub enum OrganisationRole { + User, + Admin, +} + +#[derive(Deserialize, Serialize, FromRow)] +pub struct Member { + pub id: i64, + pub name: String, + pub role: OrganisationRole, +} + +#[derive(Deserialize, Serialize)] +pub struct MemberList { + pub members: Vec, +} + +#[derive(Deserialize, Serialize)] +pub struct AdminUpdateList { + pub members: Vec, +} + +#[derive(Deserialize, Serialize)] +pub struct AdminToRemove { + pub user_id: i64, +} + +impl Organisation { + pub async fn create( + admin_id: i64, + name: String, + mut snowflake_generator: SnowflakeIdGenerator, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result<(), ChaosError> { + let id = snowflake_generator.generate(); + + sqlx::query!( + " + INSERT INTO organisations (id, name) + VALUES ($1, $2) + ", + id, + name + ) + .execute(transaction.deref_mut()) + .await?; + + sqlx::query!( + " + INSERT INTO organisation_members (organisation_id, user_id, role) + VALUES ($1, $2, $3) + ", + id, + admin_id, + OrganisationRole::Admin as OrganisationRole + ) + .execute(transaction.deref_mut()) + .await?; + + Ok(()) + } + + pub async fn get(id: i64, pool: &Pool) -> Result { + let organisation = sqlx::query_as!( + OrganisationDetails, + " + SELECT id, name, logo, created_at + FROM organisations + WHERE id = $1 + ", + id + ) + .fetch_one(pool) + .await?; + + Ok(organisation) + } + + pub async fn delete(id: i64, pool: &Pool) -> Result<(), ChaosError> { + sqlx::query!( + " + DELETE FROM organisations WHERE id = $1 + ", + id + ) + .execute(pool) + .await?; + + Ok(()) + } + + pub async fn get_admins( + organisation_id: i64, + pool: &Pool, + ) -> Result { + let admin_list = sqlx::query_as!( + Member, + " + SELECT organisation_members.user_id as id, organisation_members.role AS \"role: OrganisationRole\", users.name from organisation_members + LEFT JOIN users on users.id = organisation_members.user_id + WHERE organisation_members.organisation_id = $1 AND organisation_members.role = $2 + ", + organisation_id, + OrganisationRole::Admin as OrganisationRole + ) + .fetch_all(pool) + .await?; + + Ok(MemberList { + members: admin_list, + }) + } + + pub async fn get_members( + organisation_id: i64, + pool: &Pool, + ) -> Result { + let admin_list = sqlx::query_as!( + Member, + " + SELECT organisation_members.user_id as id, organisation_members.role AS \"role: OrganisationRole\", users.name from organisation_members + LEFT JOIN users on users.id = organisation_members.user_id + WHERE organisation_members.organisation_id = $1 + ", + organisation_id + ) + .fetch_all(pool) + .await?; + + Ok(MemberList { + members: admin_list, + }) + } + + pub async fn update_admins( + organisation_id: i64, + admin_id_list: Vec, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result<(), ChaosError> { + sqlx::query!( + "DELETE FROM organisation_members WHERE organisation_id = $1 AND role = $2", + organisation_id, + OrganisationRole::Admin as OrganisationRole + ) + .execute(transaction.deref_mut()) + .await?; + + for admin_id in admin_id_list { + sqlx::query!( + " + INSERT INTO organisation_members (organisation_id, user_id, role) + VALUES ($1, $2, $3) + ", + organisation_id, + admin_id, + OrganisationRole::Admin as OrganisationRole + ) + .execute(transaction.deref_mut()) + .await?; + } + + Ok(()) + } + + pub async fn update_members( + organisation_id: i64, + member_id_list: Vec, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result<(), ChaosError> { + sqlx::query!( + "DELETE FROM organisation_members WHERE organisation_id = $1 AND role = $2", + organisation_id, + OrganisationRole::User as OrganisationRole + ) + .execute(transaction.deref_mut()) + .await?; + + for member_id in member_id_list { + sqlx::query!( + " + INSERT INTO organisation_members (organisation_id, user_id, role) + VALUES ($1, $2, $3) + ", + organisation_id, + member_id, + OrganisationRole::User as OrganisationRole + ) + .execute(transaction.deref_mut()) + .await?; + } + + Ok(()) + } + + pub async fn remove_admin( + organisation_id: i64, + admin_to_remove: i64, + pool: &Pool, + ) -> Result<(), ChaosError> { + sqlx::query!( + " + UPDATE organisation_members SET role = $3 WHERE user_id = $1 AND organisation_id = $2 + ", + admin_to_remove, + organisation_id, + OrganisationRole::User as OrganisationRole + ) + .execute(pool) + .await?; + + Ok(()) + } + + pub async fn remove_member( + organisation_id: i64, + user_id: i64, + pool: &Pool, + ) -> Result<(), ChaosError> { + sqlx::query!( + " + DELETE FROM organisation_members WHERE user_id = $1 AND organisation_id = $2 + ", + user_id, + organisation_id + ) + .execute(pool) + .await?; + + Ok(()) + } + + pub async fn update_logo( + id: i64, + pool: &Pool, + storage_bucket: &Bucket, + ) -> Result { + let dt = Utc::now(); + + let logo_id = Uuid::new_v4().to_string(); // TODO: Change db type to UUID + let current_time = dt; + sqlx::query!( + " + UPDATE organisations + SET logo = $2, updated_at = $3 + WHERE id = $1 + ", + id, + logo_id, + current_time + ) + .execute(pool) + .await?; + + // TODO: Handle MIME type on FE and BE and handle in S3 upload + let image_id = Uuid::new_v4(); + let upload_url = + Storage::generate_put_url(format!("/{id}/{image_id}"), storage_bucket).await?; + + Ok(upload_url) + } + + pub async fn get_campaigns( + organisation_id: i64, + pool: &Pool, + ) -> Result, ChaosError> { + let campaigns = sqlx::query_as!( + Campaign, + " + SELECT id, name, cover_image, description, starts_at, ends_at + FROM campaigns + WHERE organisation_id = $1 + ", + organisation_id + ) + .fetch_all(pool) + .await?; + + Ok(campaigns) + } + + pub async fn create_campaign( + name: String, + description: Option, + starts_at: DateTime, + ends_at: DateTime, + pool: &Pool, + snowflake_id_generator: &mut SnowflakeIdGenerator, + ) -> Result<(), ChaosError> { + let new_campaign_id = snowflake_id_generator.real_time_generate(); + + sqlx::query!( + " + INSERT INTO campaigns (id, name, description, starts_at, ends_at) + VALUES ($1, $2, $3, $4, $5) + ", + new_campaign_id, + name, + description, + starts_at, + ends_at + ) + .execute(pool) + .await?; + + Ok(()) + } +} diff --git a/backend/server/src/models/storage.rs b/backend/server/src/models/storage.rs new file mode 100644 index 000000000..53b63b968 --- /dev/null +++ b/backend/server/src/models/storage.rs @@ -0,0 +1,54 @@ +use crate::models::error::ChaosError; +use s3::creds::Credentials; +use s3::{Bucket, BucketConfiguration, Region}; +use std::env; + +pub struct Storage; + +impl Storage { + pub fn init_bucket() -> Bucket { + let bucket_name = env::var("S3_BUCKET_NAME") + .expect("Error getting S3 BUCKET NAME") + .to_string(); + let access_key = env::var("S3_ACCESS_KEY") + .expect("Error getting S3 CREDENTIALS") + .to_string(); + let secret_key = env::var("S3_SECRET_KEY") + .expect("Error getting S3 CREDENTIALS") + .to_string(); + let endpoint = env::var("S3_ENDPOINT") + .expect("Error getting S3 ENDPOINT") + .to_string(); + let region_name = env::var("S3_REGION_NAME") + .expect("Error getting S3 REGION NAME") + .to_string(); + + let credentials = Credentials::new( + Option::from(access_key.as_str()), + Option::from(secret_key.as_str()), + None, + None, + None, + ) + .unwrap(); + + let region = Region::Custom { + region: region_name, + endpoint, + }; + + let config = BucketConfiguration::default(); + + let mut bucket = Bucket::new(&*bucket_name, region, credentials).unwrap(); + // TODO: Change depending on style used by provider + // bucket.set_path_style(); + + bucket + } + + pub async fn generate_put_url(path: String, bucket: &Bucket) -> Result { + let url = bucket.presign_put(path, 3600, None).await?; + + Ok(url) + } +} diff --git a/backend/server/src/models/transaction.rs b/backend/server/src/models/transaction.rs new file mode 100644 index 000000000..529f6320a --- /dev/null +++ b/backend/server/src/models/transaction.rs @@ -0,0 +1,27 @@ +use crate::models::app::AppState; +use crate::models::error::ChaosError; +use axum::async_trait; +use axum::extract::{FromRef, FromRequestParts}; +use axum::http::request::Parts; +use sqlx::{Postgres, Transaction}; + +pub struct DBTransaction<'a> { + pub tx: Transaction<'a, Postgres>, +} + +#[async_trait] +impl FromRequestParts for DBTransaction<'_> +where + AppState: FromRef, + S: Send + Sync, +{ + type Rejection = ChaosError; + + async fn from_request_parts(_: &mut Parts, state: &S) -> Result { + let app_state = AppState::from_ref(state); + + Ok(DBTransaction { + tx: app_state.db.begin().await?, + }) + } +} diff --git a/backend/server/src/models/user.rs b/backend/server/src/models/user.rs index 1f99f52f1..82c8f042d 100644 --- a/backend/server/src/models/user.rs +++ b/backend/server/src/models/user.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; #[derive(Deserialize, Serialize, sqlx::Type, Clone)] -#[sqlx(type_name = "UserRole", rename_all = "PascalCase")] +#[sqlx(type_name = "user_role", rename_all = "PascalCase")] pub enum UserRole { User, SuperUser, diff --git a/backend/server/src/service/auth.rs b/backend/server/src/service/auth.rs index 7da5a35b1..cf136cfd2 100644 --- a/backend/server/src/service/auth.rs +++ b/backend/server/src/service/auth.rs @@ -1,7 +1,7 @@ +use crate::models::user::UserRole; use anyhow::Result; use snowflake::SnowflakeIdGenerator; use sqlx::{Pool, Postgres}; -use crate::models::user::UserRole; /// Checks if a user exists in DB based on given email address. If so, their user_id is returned. /// Otherwise, a new user is created in the DB, and the new id is returned. diff --git a/backend/server/src/service/jwt.rs b/backend/server/src/service/jwt.rs index c7db35cbb..bddce8043 100644 --- a/backend/server/src/service/jwt.rs +++ b/backend/server/src/service/jwt.rs @@ -1,5 +1,5 @@ -use jsonwebtoken::{decode, encode, EncodingKey, Header, Validation}; use jsonwebtoken::DecodingKey; +use jsonwebtoken::{decode, encode, EncodingKey, Header, Validation}; use serde::{Deserialize, Serialize}; use std::time::{Duration, SystemTime, UNIX_EPOCH}; use uuid::Uuid; diff --git a/backend/server/src/service/mod.rs b/backend/server/src/service/mod.rs index 6e59a7bbd..5e708b6b4 100644 --- a/backend/server/src/service/mod.rs +++ b/backend/server/src/service/mod.rs @@ -1,3 +1,4 @@ pub mod auth; pub mod jwt; pub mod oauth2; +pub mod organisation; diff --git a/backend/server/src/service/organisation.rs b/backend/server/src/service/organisation.rs new file mode 100644 index 000000000..a29a1716b --- /dev/null +++ b/backend/server/src/service/organisation.rs @@ -0,0 +1,28 @@ +use crate::models::campaign::Campaign; +use crate::models::error::ChaosError; +use crate::models::organisation::{Member, MemberList, OrganisationDetails, OrganisationRole}; +use chrono::{DateTime, Utc}; +use snowflake::SnowflakeIdGenerator; +use sqlx::{Pool, Postgres, Transaction}; +use std::ops::DerefMut; +use uuid::Uuid; + +pub async fn user_is_admin( + user_id: i64, + organisation_id: i64, + pool: &Pool, +) -> Result<(), ChaosError> { + let is_admin = sqlx::query!( + "SELECT EXISTS(SELECT 1 FROM organisation_members WHERE organisation_id = $1 AND user_id = $2 AND role = 'Admin')", + organisation_id, + user_id + ) + .fetch_one(pool) + .await?.exists.expect("`exists` should always exist in this query result"); + + if !is_admin { + return Err(ChaosError::Unauthorized); + } + + Ok(()) +} From 16972dad6038d36fb014b6c441728ca754514e38 Mon Sep 17 00:00:00 2001 From: Fritz Rehde Date: Thu, 11 Jul 2024 18:00:02 +1000 Subject: [PATCH 27/56] feat(backend): added database dev env install script (#495) --- backend/README.md | 20 +++++++++ backend/setup-dev-env.sh | 75 +++++++++++++++++++++++++++++++++ backend/setup-test-database.yml | 17 ++++++++ 3 files changed, 112 insertions(+) create mode 100755 backend/setup-dev-env.sh create mode 100644 backend/setup-test-database.yml diff --git a/backend/README.md b/backend/README.md index 3ac95fbcf..ae44afe55 100644 --- a/backend/README.md +++ b/backend/README.md @@ -2,7 +2,26 @@ CHAOS' backend is implemented in Rust and for data persistence, we use PostgreSQL. +## Table of Contents + +- [Dev Setup](#dev-setup) +- [Code Structure](#code-structure) +- [Tech Stack](#tech-stack) + + +## Dev Setup + +To run the backend in a dev/testing environment: +1. Install `docker-compose` (see [official installation guide](https://docs.docker.com/compose/install/)). +2. Navigate to the directory this file is in (`backend`) in your terminal (not `backend/server`). +3. Possibly terminate any running instances of postgres, as the dockerized postgres we will spawn uses the same default port, so the two might interefere with each other. +4. Run `./setup-dev-env.sh` (you might have to make it executable before with `chmod +x setup-dev-env.sh`), which should drop you into a new shell that has the required tools installed. +5. Now, you can `cd server` and should be able to `cargo build` successfully. +6. Once you exit out of the newly created shell (e.g. type `exit`, or kill the terminal), the dockerized postgres instance should automatically be torn down, so it's not unnecessarily running in the background all the time. + + ## Code Structure + ### Service The service module contains all functions that conduct business logic, and also interact with the database. This separation from the request handling makes it easy to swap out any new form of requests, but reuse the same business @@ -27,6 +46,7 @@ Request -> Middleware (optional) -> Handler -> Service -> Middleware (Optional) ## Tech Stack + ### Web Server - [Axum](https://github.com/tokio-rs/axum) diff --git a/backend/setup-dev-env.sh b/backend/setup-dev-env.sh new file mode 100755 index 000000000..d7257648c --- /dev/null +++ b/backend/setup-dev-env.sh @@ -0,0 +1,75 @@ +#!/bin/sh + +# Drop the caller into a new shell that has the required dependencies, namely +# postgres and sqlx, installed and running. This is required because the Rust +# backend can only be built and run if the database is also running, due to +# sqlx. + +# Create .env file. +env_file=.env +if [ -f "$env_file" ]; then + while true; do + printf "You already have a $env_file file, are you sure you want to continue, as this will override your $env_file file? [yn] " + read -r answer + case "$answer" in + y) + # Continue with execution. + break + ;; + n) + echo "Aborting" + exit 0 + ;; + *) + # Try again. + echo "Invalid answer. Please type either 'y' for yes, or 'n' for no." + continue + ;; + esac + done +fi + +echo "Overwriting $env_file file" + +cat << 'EOF' > "$env_file" +DATABASE_URL="postgres://user:password@localhost:5432/chaos" +JWT_SECRET="test_secret" +GOOGLE_CLIENT_ID="test" +GOOGLE_CLIENT_SECRET="test" +GOOGLE_REDIRECT_URI="http://localhost:3000/auth/callback" +S3_BUCKET_NAME="chaos-storage" +S3_ACCESS_KEY="test_access_key" +S3_SECRET_KEY="test_secret_key" +S3_ENDPOINT="https://chaos-storage.s3.ap-southeast-1.amazonaws.com" +S3_REGION_NAME="ap-southeast-1" +EOF + +# Install sqlx if it isn't installed yet. +if ! which sqlx >/dev/null; then + echo "Installing sqlx" + cargo install sqlx-cli --no-default-features --features native-tls,postgres +else + echo "sqlx already installed" +fi + +# Run postgres database in the background. +this_script_dir="$(dirname "$(realpath "$0")")" +docker_compose_file_name="setup-test-database.yml" +docker_compose_file_path="$this_script_dir/$docker_compose_file_name" + +echo 'Starting up postgres database in docker' +docker-compose -f "$docker_compose_file_path" up --detach + +# Ensure the docker container gets killed once this script exits. +trap 'echo "shutting down $docker_compose_file_path" && docker-compose -f "$docker_compose_file_path" down' EXIT + +# Wait for the database to be ready. +echo "Waiting for database to be ready" +sleep 3 + +# Setup sqlx. +echo "Setting up sqlx" +sqlx database create +sqlx migrate run + +"$SHELL" diff --git a/backend/setup-test-database.yml b/backend/setup-test-database.yml new file mode 100644 index 000000000..d30d0b4e4 --- /dev/null +++ b/backend/setup-test-database.yml @@ -0,0 +1,17 @@ +# Run `docker-compose -f setup-test-database.yml up` + +services: + database: + # Official Postgres image from DockerHub. + image: 'postgres:16' + + # By default, a Postgres database is running on port 5432, so make that port accessible from outside of the container. + ports: + - 5432:5432 + + environment: + # Username and password to access database. + POSTGRES_USER: user + POSTGRES_PASSWORD: password + # Name of the database. + POSTGRES_DB: chaos From ff4cff40803de279894a1014a6e8a7f5b047a195 Mon Sep 17 00:00:00 2001 From: Yunshu Dai <67492876+pigeonseverywhere@users.noreply.github.com> Date: Sat, 20 Jul 2024 17:36:02 +1000 Subject: [PATCH 28/56] Chaos 463 campaigns crud (#486) * boilerplate for campaign * service layer for get, patch,put delete * handler updates * handler layer finalised * updated campaigns * fixed patch issue * remove empty `service/campaign.rs` file * add `organisation_name` to campaign details response * fix indentation of query code * change `cover_image` column type to UUID * minor changes * ran `cargo fmt` * remove unused `state` param * insert `organisation_id` when creating new campaign * change `organisations` logo column to `UUID` --------- Co-authored-by: Kavika --- .../20240406024211_create_organisations.sql | 2 +- .../20240406025537_create_campaigns.sql | 2 +- backend/server/src/handler/campaign.rs | 57 +++++++ backend/server/src/handler/mod.rs | 1 + backend/server/src/handler/organisation.rs | 5 +- backend/server/src/main.rs | 14 +- backend/server/src/models/auth.rs | 45 +++++- backend/server/src/models/campaign.rs | 152 +++++++++++++++++- backend/server/src/models/organisation.rs | 32 ++-- backend/server/src/models/storage.rs | 4 +- backend/server/src/service/campaign.rs | 30 ++++ backend/server/src/service/mod.rs | 1 + backend/server/src/service/organisation.rs | 10 +- 13 files changed, 318 insertions(+), 37 deletions(-) create mode 100644 backend/server/src/handler/campaign.rs create mode 100644 backend/server/src/service/campaign.rs diff --git a/backend/migrations/20240406024211_create_organisations.sql b/backend/migrations/20240406024211_create_organisations.sql index 2e9c8bf77..8c2326fb1 100644 --- a/backend/migrations/20240406024211_create_organisations.sql +++ b/backend/migrations/20240406024211_create_organisations.sql @@ -1,7 +1,7 @@ CREATE TABLE organisations ( id BIGINT PRIMARY KEY, name TEXT NOT NULL UNIQUE, - logo TEXT, + logo UUID, created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL, updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL ); diff --git a/backend/migrations/20240406025537_create_campaigns.sql b/backend/migrations/20240406025537_create_campaigns.sql index c49df429a..a23d0026d 100644 --- a/backend/migrations/20240406025537_create_campaigns.sql +++ b/backend/migrations/20240406025537_create_campaigns.sql @@ -2,7 +2,7 @@ CREATE TABLE campaigns ( id BIGINT PRIMARY KEY, organisation_id BIGINT NOT NULL, name TEXT NOT NULL, - cover_image TEXT, + cover_image UUID, description TEXT, starts_at TIMESTAMPTZ NOT NULL, ends_at TIMESTAMPTZ NOT NULL, diff --git a/backend/server/src/handler/campaign.rs b/backend/server/src/handler/campaign.rs new file mode 100644 index 000000000..a9a51776f --- /dev/null +++ b/backend/server/src/handler/campaign.rs @@ -0,0 +1,57 @@ +use crate::models; +use crate::models::app::AppState; +use crate::models::auth::AuthUser; +use crate::models::auth::CampaignAdmin; +use crate::models::campaign::Campaign; +use crate::models::error::ChaosError; +use axum::extract::{Json, Path, State}; +use axum::http::StatusCode; +use axum::response::IntoResponse; + +pub struct CampaignHandler; +impl CampaignHandler { + pub async fn get( + State(state): State, + Path(id): Path, + _user: AuthUser, + ) -> Result { + let campaign = Campaign::get(id, &state.db).await?; + Ok((StatusCode::OK, Json(campaign))) + } + + pub async fn get_all( + State(state): State, + _user: AuthUser, + ) -> Result { + let campaigns = Campaign::get_all(&state.db).await?; + Ok((StatusCode::OK, Json(campaigns))) + } + + pub async fn update( + State(state): State, + Path(id): Path, + _admin: CampaignAdmin, + Json(request_body): Json, + ) -> Result { + Campaign::update(id, request_body, &state.db).await?; + Ok((StatusCode::OK, "Successfully updated campaign")) + } + + pub async fn update_banner( + State(state): State, + Path(id): Path, + _admin: CampaignAdmin, + ) -> Result { + let banner_url = Campaign::update_banner(id, &state.db, &state.storage_bucket).await?; + Ok((StatusCode::OK, Json(banner_url))) + } + + pub async fn delete( + State(state): State, + Path(id): Path, + _admin: CampaignAdmin, + ) -> Result { + Campaign::delete(id, &state.db).await?; + Ok((StatusCode::OK, "Successfully deleted campaign")) + } +} diff --git a/backend/server/src/handler/mod.rs b/backend/server/src/handler/mod.rs index 163c47590..43f0276e1 100644 --- a/backend/server/src/handler/mod.rs +++ b/backend/server/src/handler/mod.rs @@ -1,2 +1,3 @@ pub mod auth; +pub mod campaign; pub mod organisation; diff --git a/backend/server/src/handler/organisation.rs b/backend/server/src/handler/organisation.rs index e1f08100b..78ec8bc6e 100644 --- a/backend/server/src/handler/organisation.rs +++ b/backend/server/src/handler/organisation.rs @@ -5,7 +5,6 @@ use crate::models::auth::{AuthUser, OrganisationAdmin}; use crate::models::error::ChaosError; use crate::models::organisation::{AdminToRemove, AdminUpdateList, NewOrganisation, Organisation}; use crate::models::transaction::DBTransaction; -use crate::service; use axum::extract::{Json, Path, State}; use axum::http::StatusCode; use axum::response::IntoResponse; @@ -68,7 +67,6 @@ impl OrganisationHandler { } pub async fn update_admins( - State(state): State, Path(id): Path, _super_user: SuperUser, mut transaction: DBTransaction<'_>, @@ -81,7 +79,6 @@ impl OrganisationHandler { } pub async fn update_members( - State(state): State, mut transaction: DBTransaction<'_>, Path(id): Path, _admin: OrganisationAdmin, @@ -141,11 +138,13 @@ impl OrganisationHandler { } pub async fn create_campaign( + Path(id): Path, State(mut state): State, _admin: OrganisationAdmin, Json(request_body): Json, ) -> Result { Organisation::create_campaign( + id, request_body.name, request_body.description, request_body.starts_at, diff --git a/backend/server/src/main.rs b/backend/server/src/main.rs index 38b2022c9..faa04639a 100644 --- a/backend/server/src/main.rs +++ b/backend/server/src/main.rs @@ -1,8 +1,9 @@ use crate::handler::auth::google_callback; +use crate::handler::campaign::CampaignHandler; use crate::handler::organisation::OrganisationHandler; use crate::models::storage::Storage; use anyhow::Result; -use axum::routing::{get, patch, post, put}; +use axum::routing::{get, patch, post}; use axum::Router; use jsonwebtoken::{Algorithm, DecodingKey, EncodingKey, Header, Validation}; use models::app::AppState; @@ -89,6 +90,17 @@ async fn main() -> Result<()> { .put(OrganisationHandler::update_admins) .delete(OrganisationHandler::remove_admin), ) + .route( + "/api/v1/campaign/:id", + get(CampaignHandler::get) + .put(CampaignHandler::update) + .delete(CampaignHandler::delete), + ) + .route("/api/v1/campaign", get(CampaignHandler::get_all)) + .route( + "/api/v1/campaign/:id/banner", + patch(CampaignHandler::update_banner), + ) .with_state(state); let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); diff --git a/backend/server/src/models/auth.rs b/backend/server/src/models/auth.rs index b5e9c2980..4d89dedd2 100644 --- a/backend/server/src/models/auth.rs +++ b/backend/server/src/models/auth.rs @@ -1,8 +1,9 @@ use crate::models::app::AppState; use crate::models::error::ChaosError; use crate::service::auth::is_super_user; +use crate::service::campaign::user_is_campaign_admin; use crate::service::jwt::decode_auth_token; -use crate::service::organisation::user_is_admin; +use crate::service::organisation::user_is_organisation_admin; use axum::extract::{FromRef, FromRequestParts, Path}; use axum::http::request::Parts; use axum::response::{IntoResponse, Redirect, Response}; @@ -139,8 +140,48 @@ where .await .map_err(|_| ChaosError::BadRequest)?; - user_is_admin(user_id, organisation_id, pool).await?; + user_is_organisation_admin(user_id, organisation_id, pool).await?; Ok(OrganisationAdmin { user_id }) } } + +pub struct CampaignAdmin { + pub user_id: i64, +} + +#[async_trait] +impl FromRequestParts for CampaignAdmin +where + AppState: FromRef, + S: Send + Sync, +{ + type Rejection = ChaosError; + + async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { + let app_state = AppState::from_ref(state); + let decoding_key = &app_state.decoding_key; + let jwt_validator = &app_state.jwt_validator; + let TypedHeader(cookies) = parts + .extract::>() + .await + .map_err(|_| ChaosError::NotLoggedIn)?; + + let token = cookies.get("auth_token").ok_or(ChaosError::NotLoggedIn)?; + + let claims = + decode_auth_token(token, decoding_key, jwt_validator).ok_or(ChaosError::NotLoggedIn)?; + + let pool = &app_state.db; + let user_id = claims.sub; + + let Path(campaign_id) = parts + .extract::>() + .await + .map_err(|_| ChaosError::BadRequest)?; + + user_is_campaign_admin(user_id, campaign_id, pool).await?; + + Ok(CampaignAdmin { user_id }) + } +} diff --git a/backend/server/src/models/campaign.rs b/backend/server/src/models/campaign.rs index a139900c1..40590feef 100644 --- a/backend/server/src/models/campaign.rs +++ b/backend/server/src/models/campaign.rs @@ -1,12 +1,160 @@ use chrono::{DateTime, Utc}; +use s3::Bucket; use serde::{Deserialize, Serialize}; +use sqlx::FromRow; +use sqlx::{Pool, Postgres}; +use uuid::Uuid; -#[derive(Deserialize, Serialize, Clone, Debug)] +use super::{error::ChaosError, storage::Storage}; + +#[derive(Deserialize, Serialize, Clone, FromRow, Debug)] pub struct Campaign { pub id: i64, pub name: String, + pub organisation_id: i64, + pub organisation_name: String, + pub cover_image: Option, pub description: Option, - pub cover_image: Option, pub starts_at: DateTime, pub ends_at: DateTime, + pub created_at: DateTime, + pub updated_at: DateTime, +} + +#[derive(Deserialize, Serialize, Clone, FromRow, Debug)] +pub struct CampaignDetails { + pub id: i64, + pub name: String, + pub organisation_id: i64, + pub organisation_name: String, + pub cover_image: Option, + pub description: Option, + pub starts_at: DateTime, + pub ends_at: DateTime, +} +#[derive(Deserialize, Serialize, Clone, FromRow, Debug)] +pub struct OrganisationCampaign { + pub id: i64, + pub name: String, + pub cover_image: Option, + pub description: Option, + pub starts_at: DateTime, + pub ends_at: DateTime, +} + +#[derive(Deserialize, Serialize, Clone, FromRow, Debug)] +pub struct CampaignUpdate { + pub name: String, + pub description: String, + pub starts_at: DateTime, + pub ends_at: DateTime, +} + +#[derive(Serialize)] +pub struct CampaignBannerUpdate { + pub upload_url: String, +} + +impl Campaign { + /// Get a list of all campaigns, both published and unpublished + pub async fn get_all(pool: &Pool) -> Result, ChaosError> { + let campaigns = sqlx::query_as!( + Campaign, + " + SELECT c.*, o.name as organisation_name FROM campaigns c + JOIN organisations o on c.organisation_id = o.id + " + ) + .fetch_all(pool) + .await?; + + Ok(campaigns) + } + + /// Get a campaign based on it's id + pub async fn get(id: i64, pool: &Pool) -> Result { + let campaign = sqlx::query_as!( + CampaignDetails, + " + SELECT c.id, c.name, c.organisation_id, o.name as organisation_name, + c.cover_image, c.description, c.starts_at, c.ends_at + FROM campaigns c + JOIN organisations o on c.organisation_id = o.id + WHERE c.id = $1 + ", + id + ) + .fetch_one(pool) + .await?; + + Ok(campaign) + } + + /// Update a campaign for all fields that are not None + pub async fn update( + id: i64, + update: CampaignUpdate, + pool: &Pool, + ) -> Result<(), ChaosError> { + sqlx::query!( + " + UPDATE campaigns + SET name = $1, description = $2, starts_at = $3, ends_at = $4 + WHERE id = $5 + ", + update.name, + update.description, + update.starts_at, + update.ends_at, + id + ) + .execute(pool) + .await?; + + Ok(()) + } + + /// Update a campaign banner + /// Returns the updated campaign + pub async fn update_banner( + id: i64, + pool: &Pool, + storage_bucket: &Bucket, + ) -> Result { + let dt = Utc::now(); + let image_id = Uuid::new_v4(); + let current_time = dt; + + sqlx::query!( + " + UPDATE campaigns + SET cover_image = $1, updated_at = $2 + WHERE id = $3 + ", + image_id, + current_time, + id + ) + .execute(pool) + .await?; + + let upload_url = + Storage::generate_put_url(format!("/banner/{id}/{image_id}"), storage_bucket).await?; + + Ok(CampaignBannerUpdate { upload_url }) + } + + /// Delete a campaign from the database + pub async fn delete(id: i64, pool: &Pool) -> Result<(), ChaosError> { + sqlx::query!( + " + DELETE FROM campaigns WHERE id = $1 + ", + id + ) + .execute(pool) + .await?; + + Ok(()) + } } diff --git a/backend/server/src/models/organisation.rs b/backend/server/src/models/organisation.rs index d21bd50d7..984deef3d 100644 --- a/backend/server/src/models/organisation.rs +++ b/backend/server/src/models/organisation.rs @@ -1,4 +1,4 @@ -use crate::models::campaign::Campaign; +use crate::models::campaign::OrganisationCampaign; use crate::models::error::ChaosError; use crate::models::storage::Storage; use chrono::{DateTime, Utc}; @@ -13,10 +13,10 @@ use uuid::Uuid; pub struct Organisation { pub id: i64, pub name: String, - pub logo: Option, + pub logo: Option, pub created_at: DateTime, pub updated_at: DateTime, - pub campaigns: Vec, // Awaiting Campaign to be complete - remove comment once done + pub campaigns: Vec, // Awaiting Campaign to be complete - remove comment once done pub organisation_admins: Vec, } @@ -30,7 +30,7 @@ pub struct NewOrganisation { pub struct OrganisationDetails { pub id: i64, pub name: String, - pub logo: Option, + pub logo: Option, pub created_at: DateTime, } @@ -274,7 +274,7 @@ impl Organisation { ) -> Result { let dt = Utc::now(); - let logo_id = Uuid::new_v4().to_string(); // TODO: Change db type to UUID + let logo_id = Uuid::new_v4(); let current_time = dt; sqlx::query!( " @@ -289,10 +289,8 @@ impl Organisation { .execute(pool) .await?; - // TODO: Handle MIME type on FE and BE and handle in S3 upload - let image_id = Uuid::new_v4(); let upload_url = - Storage::generate_put_url(format!("/{id}/{image_id}"), storage_bucket).await?; + Storage::generate_put_url(format!("/logo/{id}/{logo_id}"), storage_bucket).await?; Ok(upload_url) } @@ -300,14 +298,14 @@ impl Organisation { pub async fn get_campaigns( organisation_id: i64, pool: &Pool, - ) -> Result, ChaosError> { + ) -> Result, ChaosError> { let campaigns = sqlx::query_as!( - Campaign, + OrganisationCampaign, " - SELECT id, name, cover_image, description, starts_at, ends_at - FROM campaigns - WHERE organisation_id = $1 - ", + SELECT id, name, cover_image, description, starts_at, ends_at + FROM campaigns + WHERE organisation_id = $1 + ", organisation_id ) .fetch_all(pool) @@ -317,6 +315,7 @@ impl Organisation { } pub async fn create_campaign( + organisation_id: i64, name: String, description: Option, starts_at: DateTime, @@ -328,10 +327,11 @@ impl Organisation { sqlx::query!( " - INSERT INTO campaigns (id, name, description, starts_at, ends_at) - VALUES ($1, $2, $3, $4, $5) + INSERT INTO campaigns (id, organisation_id, name, description, starts_at, ends_at) + VALUES ($1, $2, $3, $4, $5, $6) ", new_campaign_id, + organisation_id, name, description, starts_at, diff --git a/backend/server/src/models/storage.rs b/backend/server/src/models/storage.rs index 53b63b968..a94c6deaf 100644 --- a/backend/server/src/models/storage.rs +++ b/backend/server/src/models/storage.rs @@ -37,9 +37,7 @@ impl Storage { endpoint, }; - let config = BucketConfiguration::default(); - - let mut bucket = Bucket::new(&*bucket_name, region, credentials).unwrap(); + let bucket = Bucket::new(&*bucket_name, region, credentials).unwrap(); // TODO: Change depending on style used by provider // bucket.set_path_style(); diff --git a/backend/server/src/service/campaign.rs b/backend/server/src/service/campaign.rs new file mode 100644 index 000000000..b9551473e --- /dev/null +++ b/backend/server/src/service/campaign.rs @@ -0,0 +1,30 @@ +use crate::models::error::ChaosError; +use sqlx::{Pool, Postgres}; + +pub async fn user_is_campaign_admin( + user_id: i64, + campaign_id: i64, + pool: &Pool, +) -> Result<(), ChaosError> { + let is_admin = sqlx::query!( + " + SELECT EXISTS( + SELECT 1 FROM campaigns c + JOIN organisation_members m on c.organisation_id = m.organisation_id + WHERE c.organisation_id = $1 AND m.user_id = $2 AND m.role = 'Admin' + ) + ", + campaign_id, + user_id + ) + .fetch_one(pool) + .await? + .exists + .expect("`exists` should always exist in this query result"); + + if !is_admin { + return Err(ChaosError::Unauthorized); + } + + Ok(()) +} diff --git a/backend/server/src/service/mod.rs b/backend/server/src/service/mod.rs index 5e708b6b4..20f4c993f 100644 --- a/backend/server/src/service/mod.rs +++ b/backend/server/src/service/mod.rs @@ -1,4 +1,5 @@ pub mod auth; +pub mod campaign; pub mod jwt; pub mod oauth2; pub mod organisation; diff --git a/backend/server/src/service/organisation.rs b/backend/server/src/service/organisation.rs index a29a1716b..31396cdcc 100644 --- a/backend/server/src/service/organisation.rs +++ b/backend/server/src/service/organisation.rs @@ -1,13 +1,7 @@ -use crate::models::campaign::Campaign; use crate::models::error::ChaosError; -use crate::models::organisation::{Member, MemberList, OrganisationDetails, OrganisationRole}; -use chrono::{DateTime, Utc}; -use snowflake::SnowflakeIdGenerator; -use sqlx::{Pool, Postgres, Transaction}; -use std::ops::DerefMut; -use uuid::Uuid; +use sqlx::{Pool, Postgres}; -pub async fn user_is_admin( +pub async fn user_is_organisation_admin( user_id: i64, organisation_id: i64, pool: &Pool, From ba6fb2b3680429099fc5ab1b613ede4a24e88af7 Mon Sep 17 00:00:00 2001 From: Alex Miao <79033892+AlexMIaoPU@users.noreply.github.com> Date: Sat, 20 Jul 2024 23:19:45 +1000 Subject: [PATCH 29/56] Campaign Role CRUD (#497) * feat: added Role struct in model, implmented get and post for Role, updated api ymal for Role, added migration to change Role table in db * feat:added methods for delte and update role;added handler for role and added some routes into main regarding role * feat: added more api yaml documentation, added handler for create and get all roles in a campaign, added get all in roles in a campagin in model * fix: changed get_roles to Campaign Handler, changede migration file * change all id columns to `BIGINT` or `BIGSERIAL` * create `RoleAdmin` struct * move `create_role()` to `CampaignHandler` * cleanup * ran cargo fmt --------- Co-authored-by: Alex_Miao_WSL Co-authored-by: Kavika --- backend/api.yaml | 235 ++++++++++++++++++ .../20240406024211_create_organisations.sql | 2 +- .../20240406025537_create_campaigns.sql | 8 +- .../20240406031400_create_questions.sql | 2 +- .../20240406031915_create_applications.sql | 10 +- backend/server/src/handler/campaign.rs | 21 ++ backend/server/src/handler/mod.rs | 1 + backend/server/src/handler/role.rs | 39 +++ backend/server/src/main.rs | 15 ++ backend/server/src/models/auth.rs | 41 +++ backend/server/src/models/mod.rs | 1 + backend/server/src/models/role.rs | 140 +++++++++++ backend/server/src/service/mod.rs | 1 + backend/server/src/service/role.rs | 34 +++ 14 files changed, 539 insertions(+), 11 deletions(-) create mode 100644 backend/server/src/handler/role.rs create mode 100644 backend/server/src/models/role.rs create mode 100644 backend/server/src/service/role.rs diff --git a/backend/api.yaml b/backend/api.yaml index 0456733a6..8b3f9ef20 100644 --- a/backend/api.yaml +++ b/backend/api.yaml @@ -817,6 +817,241 @@ paths: example: Not logged in. '403': description: User is not an organisation admin. + content: + application/json: + schema: + properties: + error: + type: string + example: Unauthorized + + /campaign/{id}/role: + post: + operationId: createRole + parameters: + - name: id + in: path + description: Campaign ID + required: true + schema: + type: integer + format: int64 + description: Creates a new role in a campaign. + tags: + - Campaign + requestBody: + required: true + content: + application/json: + schema: + properties: + name: + type: string + example: Chief Mouser + description: + type: string + required: False + example: Larry the cat is dead, now we need someone else to handle the rat issues at 10th Downing st. + min_available: + type: int32 + example: 1 + max_available: + type: int32 + example: 3 + finalised: + type: boolean + description: Whether this role has been finalised (e.g. max avaliable number) + example: False + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + message: + type: string + example: Successfully created organisation. + '403': + description: User is not a Campaign Admin. + content: + application/json: + schema: + properties: + error: + type: string + example: Unauthorized + + /campaign/{id}/roles: + get: + operationId: getRolesByCampaignId + parameters: + - name: id + in: path + description: Campaign ID + required: true + schema: + type: integer + format: int64 + description: Returns info about all roles in a campaign + tags: + - Campaign + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + campaigns: + type: array + items: + type: object + properties: + name: + type: string + example: Chief Mouser + description: + type: string + example: Larry the cat gone missing! now we need someone else to handle the rat issues at 10th Downing st. + min_available: + type: int32 + example: 1 + max_available: + type: int32 + example: 3 + finalised: + type: boolean + description: Whether this role has been finalised (e.g. max avaliable number) + example: False + /role/{id}: + get: + operationId: getRoleById + parameters: + - name: id + in: path + description: Role ID + required: true + schema: + type: integer + format: int32 + description: Returns info about specified role. + tags: + - Role + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + name: + type: string + example: Chief Mouser + description: + type: string + example: Larry the cat gone missing! now we need someone else to handle the rat issues at 10th Downing st. + min_available: + type: int32 + example: 1 + max_available: + type: int32 + example: 3 + finalised: + type: boolean + description: Whether this role has been finalised (e.g. max avaliable number) + example: False + '401': + description: Not logged in. + content: + application/json: + schema: + properties: + error: + type: string + example: Not logged in. + + put: + operationId: updateRoleById + parameters: + - name: id + in: path + description: Role ID + required: true + schema: + type: integer + format: int32 + description: Update a role given the role id. + tags: + - Role + requestBody: + required: true + content: + application/json: + schema: + properties: + name: + type: string + example: Chief Whip + description: + type: string + required: False + example: Put a bit of stick about! + min_available: + type: int32 + example: 1 + max_available: + type: int32 + example: 3 + finalised: + type: boolean + description: Whether this role has been finalised (e.g. max avaliable number) + example: true + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + message: + type: string + example: Successfully update organisation. + '403': + description: User is not a Campaign Admin. + content: + application/json: + schema: + properties: + error: + type: string + example: Unauthorized + + delete: + operationId: deleteRoleById + parameters: + - name: id + in: path + description: Role ID + required: true + schema: + type: integer + format: int32 + description: Deletes specified role. + tags: + - Role + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + message: + type: string + example: Successfully deleted role. + '403': + description: User is not an admin of role's Campaign. content: application/json: schema: diff --git a/backend/migrations/20240406024211_create_organisations.sql b/backend/migrations/20240406024211_create_organisations.sql index 8c2326fb1..24f2c18d9 100644 --- a/backend/migrations/20240406024211_create_organisations.sql +++ b/backend/migrations/20240406024211_create_organisations.sql @@ -9,7 +9,7 @@ CREATE TABLE organisations ( CREATE TYPE organisation_role AS ENUM ('User', 'Admin'); CREATE TABLE organisation_members ( - id SERIAL PRIMARY KEY, + id BIGSERIAL PRIMARY KEY, organisation_id BIGINT NOT NULL, user_id BIGINT NOT NULL, role organisation_role DEFAULT 'User' NOT NULL, diff --git a/backend/migrations/20240406025537_create_campaigns.sql b/backend/migrations/20240406025537_create_campaigns.sql index a23d0026d..ebc1311ca 100644 --- a/backend/migrations/20240406025537_create_campaigns.sql +++ b/backend/migrations/20240406025537_create_campaigns.sql @@ -16,13 +16,13 @@ CREATE TABLE campaigns ( ); CREATE TABLE campaign_roles ( - id SERIAL PRIMARY KEY, + id BIGINT PRIMARY KEY, campaign_id BIGINT NOT NULL, name TEXT NOT NULL, description TEXT, - min_available INTEGER, - max_available INTEGER, - finalised BOOLEAN, + min_available INTEGER NOT NULL, + max_available INTEGER NOT NULL, + finalised BOOLEAN NOT NULL, created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL, updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL, CONSTRAINT FK_campaign_roles_campaign diff --git a/backend/migrations/20240406031400_create_questions.sql b/backend/migrations/20240406031400_create_questions.sql index 050d07fef..8e7136afe 100644 --- a/backend/migrations/20240406031400_create_questions.sql +++ b/backend/migrations/20240406031400_create_questions.sql @@ -17,7 +17,7 @@ CREATE TABLE questions ( ); CREATE TABLE multi_option_question_options ( - id SERIAL PRIMARY KEY, + id BIGSERIAL PRIMARY KEY, text TEXT NOT NULL, question_id INTEGER NOT NULL, CONSTRAINT FK_multi_option_question_options_questions diff --git a/backend/migrations/20240406031915_create_applications.sql b/backend/migrations/20240406031915_create_applications.sql index 767abb92a..b62d6c1ab 100644 --- a/backend/migrations/20240406031915_create_applications.sql +++ b/backend/migrations/20240406031915_create_applications.sql @@ -21,7 +21,7 @@ CREATE TABLE applications ( ); CREATE TABLE application_roles ( - id SERIAL PRIMARY KEY, + id BIGSERIAL PRIMARY KEY, application_id INTEGER NOT NULL, campaign_role_id INTEGER NOT NULL, CONSTRAINT FK_application_roles_applications @@ -40,7 +40,7 @@ CREATE INDEX IDX_application_roles_applications on application_roles (applicatio CREATE INDEX IDX_application_roles_campaign_roles on application_roles (campaign_role_id); CREATE TABLE answers ( - id SERIAL PRIMARY KEY, + id BIGSERIAL PRIMARY KEY, application_id BIGINT NOT NULL, question_id BIGINT NOT NULL, CONSTRAINT FK_answers_applications @@ -59,7 +59,7 @@ CREATE INDEX IDX_answers_applications on answers (application_id); CREATE INDEX IDX_answers_questions on answers (question_id); CREATE TABLE short_answer_answers ( - id SERIAL PRIMARY KEY, + id BIGSERIAL PRIMARY KEY, text TEXT NOT NULL, answer_id INTEGER NOT NULL, CONSTRAINT FK_short_answer_answers_answers @@ -72,7 +72,7 @@ CREATE TABLE short_answer_answers ( CREATE INDEX IDX_short_answer_answers_answers on short_answer_answers (answer_id); CREATE TABLE multi_option_answer_options ( - id SERIAL PRIMARY KEY, + id BIGSERIAL PRIMARY KEY, option_id BIGINT NOT NULL, answer_id INTEGER NOT NULL, CONSTRAINT FK_multi_option_answer_options_question_options @@ -91,7 +91,7 @@ CREATE INDEX IDX_multi_option_answer_options_question_options on multi_option_an CREATE INDEX IDX_multi_option_answer_options_answers on multi_option_answer_options (answer_id); CREATE TABLE application_ratings ( - id SERIAL PRIMARY KEY, + id BIGSERIAL PRIMARY KEY, application_id BIGINT NOT NULL, rater_id BIGINT NOT NULL, rating INTEGER NOT NULL, diff --git a/backend/server/src/handler/campaign.rs b/backend/server/src/handler/campaign.rs index a9a51776f..48e152865 100644 --- a/backend/server/src/handler/campaign.rs +++ b/backend/server/src/handler/campaign.rs @@ -4,6 +4,7 @@ use crate::models::auth::AuthUser; use crate::models::auth::CampaignAdmin; use crate::models::campaign::Campaign; use crate::models::error::ChaosError; +use crate::models::role::{Role, RoleUpdate}; use axum::extract::{Json, Path, State}; use axum::http::StatusCode; use axum::response::IntoResponse; @@ -54,4 +55,24 @@ impl CampaignHandler { Campaign::delete(id, &state.db).await?; Ok((StatusCode::OK, "Successfully deleted campaign")) } + + pub async fn create_role( + State(state): State, + Path(id): Path, + _admin: CampaignAdmin, + Json(data): Json, + ) -> Result { + Role::create(id, data, &state.db, state.snowflake_generator).await?; + Ok((StatusCode::OK, "Successfully created role")) + } + + pub async fn get_roles( + State(state): State, + Path(id): Path, + _user: AuthUser, + ) -> Result { + let roles = Role::get_all_in_campaign(id, &state.db).await?; + + Ok((StatusCode::OK, Json(roles))) + } } diff --git a/backend/server/src/handler/mod.rs b/backend/server/src/handler/mod.rs index 43f0276e1..732f52dbe 100644 --- a/backend/server/src/handler/mod.rs +++ b/backend/server/src/handler/mod.rs @@ -1,3 +1,4 @@ pub mod auth; pub mod campaign; pub mod organisation; +pub mod role; diff --git a/backend/server/src/handler/role.rs b/backend/server/src/handler/role.rs new file mode 100644 index 000000000..ff569cc68 --- /dev/null +++ b/backend/server/src/handler/role.rs @@ -0,0 +1,39 @@ +use crate::models::app::AppState; +use crate::models::auth::{AuthUser, RoleAdmin}; +use crate::models::error::ChaosError; +use crate::models::role::{Role, RoleUpdate}; +use axum::extract::{Json, Path, State}; +use axum::http::StatusCode; +use axum::response::IntoResponse; + +pub struct RoleHandler; + +impl RoleHandler { + pub async fn get( + State(state): State, + Path(id): Path, + _user: AuthUser, + ) -> Result { + let role = Role::get(id, &state.db).await?; + Ok((StatusCode::OK, Json(role))) + } + + pub async fn delete( + State(state): State, + Path(id): Path, + _admin: RoleAdmin, + ) -> Result { + Role::delete(id, &state.db).await?; + Ok((StatusCode::OK, "Successfully deleted role")) + } + + pub async fn update( + State(state): State, + Path(id): Path, + _admin: RoleAdmin, + Json(data): Json, + ) -> Result { + Role::update(id, data, &state.db).await?; + Ok((StatusCode::OK, "Successfully updated role")) + } +} diff --git a/backend/server/src/main.rs b/backend/server/src/main.rs index faa04639a..7b27e12b4 100644 --- a/backend/server/src/main.rs +++ b/backend/server/src/main.rs @@ -5,6 +5,7 @@ use crate::models::storage::Storage; use anyhow::Result; use axum::routing::{get, patch, post}; use axum::Router; +use handler::role::RoleHandler; use jsonwebtoken::{Algorithm, DecodingKey, EncodingKey, Header, Validation}; use models::app::AppState; use snowflake::SnowflakeIdGenerator; @@ -90,6 +91,20 @@ async fn main() -> Result<()> { .put(OrganisationHandler::update_admins) .delete(OrganisationHandler::remove_admin), ) + .route( + "/api/v1/campaign/:id/role", + post(CampaignHandler::create_role), + ) + .route( + "/api/v1/campaign/:id/roles", + get(CampaignHandler::get_roles), + ) + .route( + "/api/v1/role/:id", + get(RoleHandler::get) + .put(RoleHandler::update) + .delete(RoleHandler::delete), + ) .route( "/api/v1/campaign/:id", get(CampaignHandler::get) diff --git a/backend/server/src/models/auth.rs b/backend/server/src/models/auth.rs index 4d89dedd2..99ef8c85a 100644 --- a/backend/server/src/models/auth.rs +++ b/backend/server/src/models/auth.rs @@ -4,6 +4,7 @@ use crate::service::auth::is_super_user; use crate::service::campaign::user_is_campaign_admin; use crate::service::jwt::decode_auth_token; use crate::service::organisation::user_is_organisation_admin; +use crate::service::role::user_is_role_admin; use axum::extract::{FromRef, FromRequestParts, Path}; use axum::http::request::Parts; use axum::response::{IntoResponse, Redirect, Response}; @@ -185,3 +186,43 @@ where Ok(CampaignAdmin { user_id }) } } + +pub struct RoleAdmin { + pub user_id: i64, +} + +#[async_trait] +impl FromRequestParts for RoleAdmin +where + AppState: FromRef, + S: Send + Sync, +{ + type Rejection = ChaosError; + + async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { + let app_state = AppState::from_ref(state); + let decoding_key = &app_state.decoding_key; + let jwt_validator = &app_state.jwt_validator; + let TypedHeader(cookies) = parts + .extract::>() + .await + .map_err(|_| ChaosError::NotLoggedIn)?; + + let token = cookies.get("auth_token").ok_or(ChaosError::NotLoggedIn)?; + + let claims = + decode_auth_token(token, decoding_key, jwt_validator).ok_or(ChaosError::NotLoggedIn)?; + + let pool = &app_state.db; + let user_id = claims.sub; + + let Path(campaign_id) = parts + .extract::>() + .await + .map_err(|_| ChaosError::BadRequest)?; + + user_is_role_admin(user_id, campaign_id, pool).await?; + + Ok(RoleAdmin { user_id }) + } +} diff --git a/backend/server/src/models/mod.rs b/backend/server/src/models/mod.rs index e5a5edb3d..76102f22e 100644 --- a/backend/server/src/models/mod.rs +++ b/backend/server/src/models/mod.rs @@ -3,6 +3,7 @@ pub mod auth; pub mod campaign; pub mod error; pub mod organisation; +pub mod role; pub mod storage; pub mod transaction; pub mod user; diff --git a/backend/server/src/models/role.rs b/backend/server/src/models/role.rs new file mode 100644 index 000000000..1d5386c73 --- /dev/null +++ b/backend/server/src/models/role.rs @@ -0,0 +1,140 @@ +use crate::models::error::ChaosError; +use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; +use snowflake::SnowflakeIdGenerator; +use sqlx::{FromRow, Pool, Postgres}; + +#[derive(Deserialize, Serialize, Clone, FromRow, Debug)] +pub struct Role { + pub id: i32, + pub campaign_id: i64, + pub name: Option, + pub description: String, + pub min_available: i32, + pub max_avaliable: i32, + pub finalised: bool, + pub created_at: DateTime, + pub updated_at: DateTime, +} + +#[derive(Deserialize, Serialize)] +pub struct RoleUpdate { + pub name: String, + pub description: Option, + pub min_available: i32, + pub max_avaliable: i32, + pub finalised: bool, +} + +#[derive(Deserialize, Serialize)] +pub struct RoleDetails { + pub name: String, + pub description: Option, + pub min_available: i32, + pub max_available: i32, + pub finalised: bool, +} + +impl Role { + pub async fn create( + campaign_id: i64, + role_data: RoleUpdate, + pool: &Pool, + mut snowflake_generator: SnowflakeIdGenerator, + ) -> Result<(), ChaosError> { + let id = snowflake_generator.generate(); + + sqlx::query!( + " + INSERT INTO campaign_roles (id, campaign_id, name, description, min_available, max_available, finalised) + VALUES ($1, $2, $3, $4, $5, $6, $7) + ", + id, + campaign_id, + role_data.name, + role_data.description, + role_data.min_available, + role_data.max_avaliable, + role_data.finalised + ) + .fetch_one(pool) + .await?; + + Ok(()) + } + + pub async fn get(id: i64, pool: &Pool) -> Result { + let role = sqlx::query_as!( + RoleDetails, + " + SELECT name, description, min_available, max_available, finalised + FROM campaign_roles + WHERE id = $1 + ", + id + ) + .fetch_one(pool) + .await?; + + Ok(role) + } + + pub async fn delete(id: i64, pool: &Pool) -> Result<(), ChaosError> { + sqlx::query!( + " + DELETE FROM campaign_roles WHERE id = $1 + ", + id + ) + .execute(pool) + .await?; + + Ok(()) + } + + pub async fn update( + id: i64, + role_data: RoleUpdate, + pool: &Pool, + ) -> Result<(), ChaosError> { + sqlx::query!( + " + UPDATE campaign_roles + SET (name, description, min_available, max_available, finalised) = ($2, $3, $4, $5, $6) + WHERE id = $1; + ", + id, + role_data.name, + role_data.description, + role_data.min_available, + role_data.max_avaliable, + role_data.finalised + ) + .fetch_one(pool) + .await?; + + Ok(()) + } + + /* + Given a campaign id, return all existing roles in this campaign + */ + pub async fn get_all_in_campaign( + campaign_id: i64, + pool: &Pool, + ) -> Result, ChaosError> { + let roles = sqlx::query_as!( + RoleDetails, + " + SELECT name, description, min_available, max_available, finalised + FROM campaign_roles + WHERE campaign_id = $1 + ", + campaign_id + ) + .fetch_all(pool) + .await?; + + Ok(roles) + } +} diff --git a/backend/server/src/service/mod.rs b/backend/server/src/service/mod.rs index 20f4c993f..b98f4e2aa 100644 --- a/backend/server/src/service/mod.rs +++ b/backend/server/src/service/mod.rs @@ -3,3 +3,4 @@ pub mod campaign; pub mod jwt; pub mod oauth2; pub mod organisation; +pub mod role; diff --git a/backend/server/src/service/role.rs b/backend/server/src/service/role.rs new file mode 100644 index 000000000..52329869e --- /dev/null +++ b/backend/server/src/service/role.rs @@ -0,0 +1,34 @@ +use crate::models::error::ChaosError; +use sqlx::{Pool, Postgres}; + +pub async fn user_is_role_admin( + user_id: i64, + role_id: i64, + pool: &Pool, +) -> Result<(), ChaosError> { + let is_admin = sqlx::query!( + " + SELECT EXISTS( + SELECT 1 FROM ( + SELECT c.organisation_id FROM campaign_roles r + JOIN campaigns c on r.campaign_id = c.id + WHERE r.id = $1 + ) cr + JOIN organisation_members m on cr.organisation_id = m.organisation_id + WHERE m.user_id = $2 AND m.role = 'Admin' + ) + ", + role_id, + user_id + ) + .fetch_one(pool) + .await? + .exists + .expect("`exists` should always exist in this query result"); + + if !is_admin { + return Err(ChaosError::Unauthorized); + } + + Ok(()) +} From f140dd6b9c6ca1911ac5dde96684b383ff4a205d Mon Sep 17 00:00:00 2001 From: Alex Miao <79033892+AlexMIaoPU@users.noreply.github.com> Date: Fri, 2 Aug 2024 15:14:50 +1000 Subject: [PATCH 30/56] Chaos 502 application crud (#503) * feat: added model file for application; added create method. fix: changed schema for application_role, fixed id type for role. * attempt to implement get for application; added additional fields for role response struct * added additional field to Application response type * feat: added get methods for application in model * fix pool usage in model/role, added set_status methods to application, patched API routes for get_all routes * added handlers for application; implemented Auth for ApplicationAdmin * added routes for applications in main; implement more handlers; moved some application handler methods to other more appropriate handlers * change `*Admin` `FromRequest` implementations to use HashMap of path variables * make 'Pending' the default Application status * return user info with `ApplicationDetails` --------- Co-authored-by: Alex_Miao_WSL Co-authored-by: Kavika --- .../20240406031915_create_applications.sql | 8 +- backend/server/src/handler/application.rs | 51 +++ backend/server/src/handler/campaign.rs | 25 ++ backend/server/src/handler/mod.rs | 1 + backend/server/src/handler/role.rs | 12 + backend/server/src/main.rs | 45 ++- backend/server/src/models/application.rs | 375 ++++++++++++++++++ backend/server/src/models/auth.rs | 66 ++- backend/server/src/models/mod.rs | 1 + backend/server/src/models/role.rs | 12 +- backend/server/src/models/user.rs | 11 + backend/server/src/service/application.rs | 36 ++ backend/server/src/service/mod.rs | 1 + 13 files changed, 615 insertions(+), 29 deletions(-) create mode 100644 backend/server/src/handler/application.rs create mode 100644 backend/server/src/models/application.rs create mode 100644 backend/server/src/service/application.rs diff --git a/backend/migrations/20240406031915_create_applications.sql b/backend/migrations/20240406031915_create_applications.sql index b62d6c1ab..e2fcd0576 100644 --- a/backend/migrations/20240406031915_create_applications.sql +++ b/backend/migrations/20240406031915_create_applications.sql @@ -4,8 +4,8 @@ CREATE TABLE applications ( id BIGINT PRIMARY KEY, campaign_id BIGINT NOT NULL, user_id BIGINT NOT NULL, - status application_status NOT NULL, - private_status application_status NOT NULL, + status application_status NOT NULL DEFAULT 'Pending', + private_status application_status NOT NULL DEFAULT 'Pending', created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL, updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL, CONSTRAINT FK_applications_campaigns @@ -22,8 +22,8 @@ CREATE TABLE applications ( CREATE TABLE application_roles ( id BIGSERIAL PRIMARY KEY, - application_id INTEGER NOT NULL, - campaign_role_id INTEGER NOT NULL, + application_id BIGINT NOT NULL, + campaign_role_id BIGINT NOT NULL, CONSTRAINT FK_application_roles_applications FOREIGN KEY(application_id) REFERENCES applications(id) diff --git a/backend/server/src/handler/application.rs b/backend/server/src/handler/application.rs new file mode 100644 index 000000000..15d75e413 --- /dev/null +++ b/backend/server/src/handler/application.rs @@ -0,0 +1,51 @@ +use crate::models::app::AppState; +use crate::models::application::{Application, ApplicationStatus}; +use crate::models::auth::{AuthUser, ApplicationAdmin}; +use crate::models::error::ChaosError; +use crate::models::transaction::DBTransaction; +use axum::extract::{Json, Path, State}; +use axum::http::StatusCode; +use axum::response::IntoResponse; + +pub struct ApplicationHandler; + +impl ApplicationHandler { + pub async fn get( + Path(application_id): Path, + _admin: ApplicationAdmin, + mut transaction: DBTransaction<'_>, + ) -> Result { + let application = Application::get(application_id, &mut transaction.tx).await?; + transaction.tx.commit().await?; + Ok((StatusCode::OK, Json(application))) + } + + pub async fn set_status( + State(state): State, + Path(application_id): Path, + _admin: ApplicationAdmin, + Json(data): Json, + ) -> Result { + Application::set_status(application_id, data, &state.db).await?; + Ok((StatusCode::OK, "Status successfully updated")) + } + + pub async fn set_private_status( + State(state): State, + Path(application_id): Path, + _admin: ApplicationAdmin, + Json(data): Json, + ) -> Result { + Application::set_private_status(application_id, data, &state.db).await?; + Ok((StatusCode::OK, "Private Status successfully updated")) + } + + pub async fn get_from_curr_user( + user: AuthUser, + mut transaction: DBTransaction<'_>, + ) -> Result { + let applications = Application::get_from_user_id(user.user_id, &mut transaction.tx).await?; + transaction.tx.commit().await?; + Ok((StatusCode::OK, Json(applications))) + } +} \ No newline at end of file diff --git a/backend/server/src/handler/campaign.rs b/backend/server/src/handler/campaign.rs index 48e152865..f5a827d36 100644 --- a/backend/server/src/handler/campaign.rs +++ b/backend/server/src/handler/campaign.rs @@ -1,10 +1,13 @@ use crate::models; use crate::models::app::AppState; +use crate::models::application::Application; +use crate::models::application::NewApplication; use crate::models::auth::AuthUser; use crate::models::auth::CampaignAdmin; use crate::models::campaign::Campaign; use crate::models::error::ChaosError; use crate::models::role::{Role, RoleUpdate}; +use crate::models::transaction::DBTransaction; use axum::extract::{Json, Path, State}; use axum::http::StatusCode; use axum::response::IntoResponse; @@ -75,4 +78,26 @@ impl CampaignHandler { Ok((StatusCode::OK, Json(roles))) } + + pub async fn create_application( + State(state): State, + Path(id): Path, + user: AuthUser, + mut transaction: DBTransaction<'_>, + Json(data): Json, + ) -> Result { + Application::create(id, user.user_id, data, state.snowflake_generator, &mut transaction.tx).await?; + transaction.tx.commit().await?; + Ok((StatusCode::OK, "Successfully created application")) + } + + pub async fn get_applications( + Path(id): Path, + _admin: CampaignAdmin, + mut transaction: DBTransaction<'_>, + ) -> Result { + let applications = Application::get_from_campaign_id(id, &mut transaction.tx).await?; + transaction.tx.commit().await?; + Ok((StatusCode::OK, Json(applications))) + } } diff --git a/backend/server/src/handler/mod.rs b/backend/server/src/handler/mod.rs index 732f52dbe..3273c2a70 100644 --- a/backend/server/src/handler/mod.rs +++ b/backend/server/src/handler/mod.rs @@ -2,3 +2,4 @@ pub mod auth; pub mod campaign; pub mod organisation; pub mod role; +pub mod application; \ No newline at end of file diff --git a/backend/server/src/handler/role.rs b/backend/server/src/handler/role.rs index ff569cc68..c1e9d2daf 100644 --- a/backend/server/src/handler/role.rs +++ b/backend/server/src/handler/role.rs @@ -1,8 +1,10 @@ use crate::models::app::AppState; +use crate::models::application::Application; use crate::models::auth::{AuthUser, RoleAdmin}; use crate::models::error::ChaosError; use crate::models::role::{Role, RoleUpdate}; use axum::extract::{Json, Path, State}; +use crate::models::transaction::DBTransaction; use axum::http::StatusCode; use axum::response::IntoResponse; @@ -36,4 +38,14 @@ impl RoleHandler { Role::update(id, data, &state.db).await?; Ok((StatusCode::OK, "Successfully updated role")) } + + pub async fn get_applications( + Path(id): Path, + _admin: RoleAdmin, + mut transaction: DBTransaction<'_>, + ) -> Result { + let applications = Application::get_from_role_id(id, &mut transaction.tx).await?; + transaction.tx.commit().await?; + Ok((StatusCode::OK, Json(applications))) + } } diff --git a/backend/server/src/main.rs b/backend/server/src/main.rs index 7b27e12b4..d2a0618c6 100644 --- a/backend/server/src/main.rs +++ b/backend/server/src/main.rs @@ -1,6 +1,7 @@ use crate::handler::auth::google_callback; use crate::handler::campaign::CampaignHandler; use crate::handler::organisation::OrganisationHandler; +use crate::handler::application::ApplicationHandler; use crate::models::storage::Storage; use anyhow::Result; use axum::routing::{get, patch, post}; @@ -66,56 +67,78 @@ async fn main() -> Result<()> { let app = Router::new() .route("/", get(|| async { "Hello, World!" })) .route("/api/auth/callback/google", get(google_callback)) + .route( + "/api/v1/user/applications", + get(ApplicationHandler::get_from_curr_user), + ) .route("/api/v1/organisation", post(OrganisationHandler::create)) .route( - "/api/v1/organisation/:id", + "/api/v1/organisation/:organisation_id", get(OrganisationHandler::get).delete(OrganisationHandler::delete), ) .route( - "/api/v1/organisation/:id/campaign", - get(OrganisationHandler::get_campaigns).post(OrganisationHandler::create_campaign), + "/api/v1/organisation/:organisation_id/campaign", + post(OrganisationHandler::create_campaign), ) .route( - "/api/v1/organisation/:id/logo", + "/api/v1/organisation/:organisation_id/campaigns", + get(OrganisationHandler::get_campaigns), + ) + .route( + "/api/v1/organisation/:organisation_id/logo", patch(OrganisationHandler::update_logo), ) .route( - "/api/v1/organisation/:id/member", + "/api/v1/organisation/:organisation_id/member", get(OrganisationHandler::get_members) .put(OrganisationHandler::update_members) .delete(OrganisationHandler::remove_member), ) .route( - "/api/v1/organisation/:id/admin", + "/api/v1/organisation/:organisation_id/admin", get(OrganisationHandler::get_admins) .put(OrganisationHandler::update_admins) .delete(OrganisationHandler::remove_admin), ) .route( - "/api/v1/campaign/:id/role", + "/api/v1/campaign/:campaign_id/role", post(CampaignHandler::create_role), ) .route( - "/api/v1/campaign/:id/roles", + "/api/v1/campaign/:campaign_id/roles", get(CampaignHandler::get_roles), ) .route( - "/api/v1/role/:id", + "/api/v1/campaign/:campaign_id/applications", + get(CampaignHandler::get_applications), + ) + .route( + "/api/v1/role/:role_id", get(RoleHandler::get) .put(RoleHandler::update) .delete(RoleHandler::delete), ) .route( - "/api/v1/campaign/:id", + "/api/v1/role/:role_id/applications", + get(RoleHandler::get_applications) + ) + .route( + "/api/v1/campaign/:campaign_id", get(CampaignHandler::get) .put(CampaignHandler::update) .delete(CampaignHandler::delete), ) .route("/api/v1/campaign", get(CampaignHandler::get_all)) .route( - "/api/v1/campaign/:id/banner", + "/api/v1/campaign/:campaign_id/banner", patch(CampaignHandler::update_banner), ) + .route("api/v1/campaign/:campaign_id/application", + post(CampaignHandler::create_application) + ) + .route("api/v1/application/:application_id", get(ApplicationHandler::get)) + .route("api/v1/application/:application_id/status", patch(ApplicationHandler::set_status)) + .route("api/v1/application/:application_id/private", patch(ApplicationHandler::set_private_status)) .with_state(state); let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); diff --git a/backend/server/src/models/application.rs b/backend/server/src/models/application.rs new file mode 100644 index 000000000..da002b22c --- /dev/null +++ b/backend/server/src/models/application.rs @@ -0,0 +1,375 @@ +use crate::models::error::ChaosError; +use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; +use snowflake::SnowflakeIdGenerator; +use sqlx::{FromRow, Pool, Postgres, Transaction}; +use std::ops::DerefMut; +use crate::models::user::User; + +#[derive(Deserialize, Serialize, Clone, FromRow, Debug)] +pub struct Application { + pub id: i64, + pub campaign_id: i64, + pub user_id: i64, + pub status: ApplicationStatus, + pub private_status: ApplicationStatus, + pub created_at: DateTime, + pub updated_at: DateTime, +} + +/* + User could apply for more than one roles at a time, for each application + into a role it will be represented by row in application_roles table which + is linked to the main Application body through application_id +*/ +#[derive(Deserialize, Serialize, Clone, FromRow, Debug)] +pub struct ApplicationRole { + pub id: i64, + pub application_id: i64, + pub campaign_role_id: i64, +} + +#[derive(Deserialize, Serialize)] +pub struct NewApplication { + pub applied_roles: Vec, +} + +#[derive(Deserialize, Serialize)] +pub struct ApplicationDetails { + pub id: i64, + pub campaign_id: i64, + pub user: User, + pub status: ApplicationStatus, + pub private_status: ApplicationStatus, + pub applied_roles: Vec +} + +#[derive(Deserialize, Serialize)] +pub struct ApplicationData { + pub id: i64, + pub campaign_id: i64, + pub user_id: i64, + pub user_email: String, + pub user_zid: Option, + pub user_name: String, + pub user_degree_name: Option, + pub user_degree_starting_year: Option, + pub status: ApplicationStatus, + pub private_status: ApplicationStatus, +} + +#[derive(Deserialize, Serialize)] +pub struct ApplicationAppliedRoleDetails { + pub campaign_role_id: i64, + pub role_name: String, +} + + +#[derive(Deserialize, Serialize, sqlx::Type, Clone, Debug)] +#[sqlx(type_name = "application_status", rename_all = "PascalCase")] +pub enum ApplicationStatus { + Pending, + Rejected, + Successful, +} + +impl Application { + pub async fn create( + campaign_id: i64, + user_id: i64, + application_data: NewApplication, + mut snowflake_generator: SnowflakeIdGenerator, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result<(), ChaosError> { + let id = snowflake_generator.generate(); + + // Insert into table applications + sqlx::query!( + " + INSERT INTO applications (id, campaign_id, user_id) + VALUES ($1, $2, $3) + ", + id, + campaign_id, + user_id + ) + .execute(transaction.deref_mut()) + .await?; + + // Insert into table application_roles + for role_applied in application_data.applied_roles { + sqlx::query!( + " + INSERT INTO application_roles (application_id, campaign_role_id) + VALUES ($1, $2) + ", + id, + role_applied.campaign_role_id + ) + .execute(transaction.deref_mut()) + .await?; + } + + Ok(()) + } + + /* + Get Application given an application id + */ + pub async fn get(id: i64, transaction: &mut Transaction<'_, Postgres>,) -> Result { + let application_data = sqlx::query_as!( + ApplicationData, + " + SELECT a.id AS id, campaign_id, user_id, status AS \"status: ApplicationStatus\", + private_status AS \"private_status: ApplicationStatus\", u.email AS user_email, + u.zid AS user_zid, u.name AS user_name, u.degree_name AS user_degree_name, + u.degree_starting_year AS user_degree_starting_year + FROM applications a LEFT JOIN users u ON u.id = a.user_id + WHERE a.id = $1 + ", + id + ) + .fetch_one(transaction.deref_mut()) + .await?; + + let applied_roles = sqlx::query_as!( + ApplicationAppliedRoleDetails, + " + SELECT application_roles.campaign_role_id, campaign_roles.name AS role_name + FROM application_roles + LEFT JOIN campaign_roles + ON application_roles.campaign_role_id = campaign_roles.id + WHERE application_id = $1 + ", + id + ) + .fetch_all(transaction.deref_mut()) + .await?; + + Ok( + ApplicationDetails { + id: application_data.id, + campaign_id: application_data.campaign_id, + status: application_data.status, + private_status: application_data.private_status, + applied_roles, + user: User { + id: application_data.user_id, + email: application_data.user_email, + zid: application_data.user_zid, + name: application_data.user_name, + degree_name: application_data.user_degree_name, + degree_starting_year: application_data.user_degree_starting_year, + }, + } + ) + } + + + /* + Get All applications that apply for a given role + */ + pub async fn get_from_role_id(role_id: i64, transaction: &mut Transaction<'_, Postgres>,) + -> Result, ChaosError> { + let application_data_list = sqlx::query_as!( + ApplicationData, + " + SELECT a.id AS id, campaign_id, user_id, status AS \"status: ApplicationStatus\", + private_status AS \"private_status: ApplicationStatus\", u.email AS user_email, + u.zid AS user_zid, u.name AS user_name, u.degree_name AS user_degree_name, + u.degree_starting_year AS user_degree_starting_year + FROM applications a LEFT JOIN users u ON u.id = a.user_id LEFT JOIN application_roles ar on ar.application_id = a.id + WHERE ar.id = $1 + ", + role_id + ) + .fetch_all(transaction.deref_mut()) + .await?; + + let mut application_details_list = Vec::new(); + for application_data in application_data_list { + let applied_roles = sqlx::query_as!( + ApplicationAppliedRoleDetails, + " + SELECT application_roles.campaign_role_id, campaign_roles.name AS role_name + FROM application_roles + LEFT JOIN campaign_roles + ON application_roles.campaign_role_id = campaign_roles.id + WHERE application_id = $1 + ", + application_data.id + ) + .fetch_all(transaction.deref_mut()) + .await?; + + let details = ApplicationDetails { + id: application_data.id, + campaign_id: application_data.campaign_id, + status: application_data.status, + private_status: application_data.private_status, + applied_roles, + user: User { + id: application_data.user_id, + email: application_data.user_email, + zid: application_data.user_zid, + name: application_data.user_name, + degree_name: application_data.user_degree_name, + degree_starting_year: application_data.user_degree_starting_year, + }, + }; + + application_details_list.push(details); + } + + Ok(application_details_list) + } + + /* + Get All applications that apply for a given campaign + */ + pub async fn get_from_campaign_id(campaign_id: i64, transaction: &mut Transaction<'_, Postgres>,) + -> Result, ChaosError> { + let application_data_list = sqlx::query_as!( + ApplicationData, + " + SELECT a.id AS id, campaign_id, user_id, status AS \"status: ApplicationStatus\", + private_status AS \"private_status: ApplicationStatus\", u.email AS user_email, + u.zid AS user_zid, u.name AS user_name, u.degree_name AS user_degree_name, + u.degree_starting_year AS user_degree_starting_year + FROM applications a LEFT JOIN users u ON u.id = a.user_id + WHERE a.campaign_id = $1 + ", + campaign_id + ) + .fetch_all(transaction.deref_mut()) + .await?; + + let mut application_details_list = Vec::new(); + for application_data in application_data_list { + let applied_roles = sqlx::query_as!( + ApplicationAppliedRoleDetails, + " + SELECT application_roles.campaign_role_id, campaign_roles.name AS role_name + FROM application_roles + LEFT JOIN campaign_roles + ON application_roles.campaign_role_id = campaign_roles.id + WHERE application_id = $1 + ", + application_data.id + ) + .fetch_all(transaction.deref_mut()) + .await?; + + let details = ApplicationDetails { + id: application_data.id, + campaign_id: application_data.campaign_id, + status: application_data.status, + private_status: application_data.private_status, + applied_roles, + user: User { + id: application_data.user_id, + email: application_data.user_email, + zid: application_data.user_zid, + name: application_data.user_name, + degree_name: application_data.user_degree_name, + degree_starting_year: application_data.user_degree_starting_year, + }, + }; + + application_details_list.push(details) + } + + Ok(application_details_list) + } + + /* + Get All applications that are made by a given user + */ + pub async fn get_from_user_id(user_id: i64, transaction: &mut Transaction<'_, Postgres>,) + -> Result, ChaosError> { + let application_data_list = sqlx::query_as!( + ApplicationData, + " + SELECT a.id AS id, campaign_id, user_id, status AS \"status: ApplicationStatus\", + private_status AS \"private_status: ApplicationStatus\", u.email AS user_email, + u.zid AS user_zid, u.name AS user_name, u.degree_name AS user_degree_name, + u.degree_starting_year AS user_degree_starting_year + FROM applications a LEFT JOIN users u ON u.id = a.user_id + WHERE a.user_id = $1 + ", + user_id + ) + .fetch_all(transaction.deref_mut()) + .await?; + + let mut application_details_list = Vec::new(); + for application_data in application_data_list { + let applied_roles = sqlx::query_as!( + ApplicationAppliedRoleDetails, + " + SELECT application_roles.campaign_role_id, campaign_roles.name AS role_name + FROM application_roles + LEFT JOIN campaign_roles + ON application_roles.campaign_role_id = campaign_roles.id + WHERE application_id = $1 + ", + application_data.id + ) + .fetch_all(transaction.deref_mut()) + .await?; + + let details = ApplicationDetails { + id: application_data.id, + campaign_id: application_data.campaign_id, + status: application_data.status, + private_status: application_data.private_status, + applied_roles, + user: User { + id: application_data.user_id, + email: application_data.user_email, + zid: application_data.user_zid, + name: application_data.user_name, + degree_name: application_data.user_degree_name, + degree_starting_year: application_data.user_degree_starting_year, + }, + }; + + application_details_list.push(details) + } + + Ok(application_details_list) + } + + pub async fn set_status(id: i64, new_status: ApplicationStatus, pool: &Pool) -> Result<(), ChaosError> { + sqlx::query!( + " + UPDATE applications + SET status = $2 + WHERE id = $1; + ", + id, + new_status as ApplicationStatus + ) + .execute(pool) + .await?; + + Ok(()) + } + + pub async fn set_private_status(id: i64, new_status: ApplicationStatus, pool: &Pool) -> Result<(), ChaosError> { + sqlx::query!( + " + UPDATE applications + SET private_status = $2 + WHERE id = $1; + ", + id, + new_status as ApplicationStatus + ) + .execute(pool) + .await?; + + Ok(()) + } + +} \ No newline at end of file diff --git a/backend/server/src/models/auth.rs b/backend/server/src/models/auth.rs index 99ef8c85a..c120284a7 100644 --- a/backend/server/src/models/auth.rs +++ b/backend/server/src/models/auth.rs @@ -1,5 +1,7 @@ +use std::collections::HashMap; use crate::models::app::AppState; use crate::models::error::ChaosError; +use crate::service::application::user_is_application_admin; use crate::service::auth::is_super_user; use crate::service::campaign::user_is_campaign_admin; use crate::service::jwt::decode_auth_token; @@ -136,10 +138,12 @@ where let pool = &app_state.db; let user_id = claims.sub; - let Path(organisation_id) = parts - .extract::>() + let organisation_id = *parts + .extract::>>() .await - .map_err(|_| ChaosError::BadRequest)?; + .map_err(|_| ChaosError::BadRequest)? + .get("organisation_id") + .ok_or(ChaosError::BadRequest)?; user_is_organisation_admin(user_id, organisation_id, pool).await?; @@ -176,10 +180,12 @@ where let pool = &app_state.db; let user_id = claims.sub; - let Path(campaign_id) = parts - .extract::>() + let campaign_id = *parts + .extract::>>() .await - .map_err(|_| ChaosError::BadRequest)?; + .map_err(|_| ChaosError::BadRequest)? + .get("campaign_id") + .ok_or(ChaosError::BadRequest)?; user_is_campaign_admin(user_id, campaign_id, pool).await?; @@ -216,13 +222,55 @@ where let pool = &app_state.db; let user_id = claims.sub; - let Path(campaign_id) = parts + let role_id = *parts + .extract::>>() + .await + .map_err(|_| ChaosError::BadRequest)? + .get("role_id") + .ok_or(ChaosError::BadRequest)?; + + user_is_role_admin(user_id, role_id, pool).await?; + + Ok(RoleAdmin { user_id }) + } +} + +pub struct ApplicationAdmin { + pub user_id: i64, +} + +#[async_trait] +impl FromRequestParts for ApplicationAdmin +where + AppState: FromRef, + S: Send + Sync, +{ + type Rejection = ChaosError; + + async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { + let app_state = AppState::from_ref(state); + let decoding_key = &app_state.decoding_key; + let jwt_validator = &app_state.jwt_validator; + let TypedHeader(cookies) = parts + .extract::>() + .await + .map_err(|_| ChaosError::NotLoggedIn)?; + + let token = cookies.get("auth_token").ok_or(ChaosError::NotLoggedIn)?; + + let claims = + decode_auth_token(token, decoding_key, jwt_validator).ok_or(ChaosError::NotLoggedIn)?; + + let pool = &app_state.db; + let user_id = claims.sub; + + let Path(application_id) = parts .extract::>() .await .map_err(|_| ChaosError::BadRequest)?; - user_is_role_admin(user_id, campaign_id, pool).await?; + user_is_application_admin(user_id, application_id, pool).await?; - Ok(RoleAdmin { user_id }) + Ok(ApplicationAdmin { user_id }) } } diff --git a/backend/server/src/models/mod.rs b/backend/server/src/models/mod.rs index 76102f22e..0af7da1a7 100644 --- a/backend/server/src/models/mod.rs +++ b/backend/server/src/models/mod.rs @@ -7,3 +7,4 @@ pub mod role; pub mod storage; pub mod transaction; pub mod user; +pub mod application; diff --git a/backend/server/src/models/role.rs b/backend/server/src/models/role.rs index 1d5386c73..a52eb1d4d 100644 --- a/backend/server/src/models/role.rs +++ b/backend/server/src/models/role.rs @@ -6,7 +6,7 @@ use sqlx::{FromRow, Pool, Postgres}; #[derive(Deserialize, Serialize, Clone, FromRow, Debug)] pub struct Role { - pub id: i32, + pub id: i64, pub campaign_id: i64, pub name: Option, pub description: String, @@ -28,6 +28,8 @@ pub struct RoleUpdate { #[derive(Deserialize, Serialize)] pub struct RoleDetails { + pub id: i64, + pub campaign_id: i64, pub name: String, pub description: Option, pub min_available: i32, @@ -57,7 +59,7 @@ impl Role { role_data.max_avaliable, role_data.finalised ) - .fetch_one(pool) + .execute(pool) .await?; Ok(()) @@ -67,7 +69,7 @@ impl Role { let role = sqlx::query_as!( RoleDetails, " - SELECT name, description, min_available, max_available, finalised + SELECT id, campaign_id, name, description, min_available, max_available, finalised FROM campaign_roles WHERE id = $1 ", @@ -110,7 +112,7 @@ impl Role { role_data.max_avaliable, role_data.finalised ) - .fetch_one(pool) + .execute(pool) .await?; Ok(()) @@ -126,7 +128,7 @@ impl Role { let roles = sqlx::query_as!( RoleDetails, " - SELECT name, description, min_available, max_available, finalised + SELECT id, campaign_id, name, description, min_available, max_available, finalised FROM campaign_roles WHERE campaign_id = $1 ", diff --git a/backend/server/src/models/user.rs b/backend/server/src/models/user.rs index 82c8f042d..f91e9ce7d 100644 --- a/backend/server/src/models/user.rs +++ b/backend/server/src/models/user.rs @@ -6,3 +6,14 @@ pub enum UserRole { User, SuperUser, } + +// Placeholder until User CRUD is merged +#[derive(Deserialize, Serialize)] +pub struct User { + pub id: i64, + pub email: String, + pub zid: Option, + pub name: String, + pub degree_name: Option, + pub degree_starting_year: Option, +} \ No newline at end of file diff --git a/backend/server/src/service/application.rs b/backend/server/src/service/application.rs new file mode 100644 index 000000000..4fdf052be --- /dev/null +++ b/backend/server/src/service/application.rs @@ -0,0 +1,36 @@ +use crate::models::error::ChaosError; +use sqlx::{Pool, Postgres}; + + +pub async fn user_is_application_admin( + user_id: i64, + application_id: i64, + pool: &Pool, +) -> Result<(), ChaosError> { + let is_admin = sqlx::query!( + " + SELECT EXISTS( + SELECT 1 FROM ( + SELECT c.organisation_id FROM applications a + JOIN campaigns c on a.campaign_id = c.id + WHERE a.id = $1 + ) ca + JOIN organisation_members m on ca.organisation_id = m.organisation_id + WHERE m.user_id = $2 AND m.role = 'Admin' + ) + ", + application_id, + user_id + ) + .fetch_one(pool) + .await? + .exists + .expect("`exists` should always exist in this query result"); + + if !is_admin { + return Err(ChaosError::Unauthorized); + } + + Ok(()) + +} \ No newline at end of file diff --git a/backend/server/src/service/mod.rs b/backend/server/src/service/mod.rs index b98f4e2aa..21940ccd7 100644 --- a/backend/server/src/service/mod.rs +++ b/backend/server/src/service/mod.rs @@ -4,3 +4,4 @@ pub mod jwt; pub mod oauth2; pub mod organisation; pub mod role; +pub mod application; From 45c83248176b29e38c50ca1aa358109b8d36bdd1 Mon Sep 17 00:00:00 2001 From: HellenMelon <153735075+HellenMelon@users.noreply.github.com> Date: Fri, 2 Aug 2024 16:07:10 +1000 Subject: [PATCH 31/56] User CRUD (#493) * added get_username for all users logged in * updted user crud * efficient user get fucntion * finished user but no testing * finished user crud * docker working file * set users `created_at` and `updated_at` to not null * set optional fields to `Option` in `User` struct * fix `query_as` with custom enums * finished user crud * changed User CRUD to use handler struct * move `User` DB logic to `models::User` file * add pronouns and gender to `User` * remove TODO comment * fixed errors and warnings with adding new user fields --------- Co-authored-by: Alex_Miao_WSL Co-authored-by: Kavika --- .../20240406023149_create_users.sql | 2 + backend/server/src/handler/mod.rs | 3 +- backend/server/src/handler/user.rs | 77 ++++++++++ backend/server/src/main.rs | 7 + backend/server/src/models/application.rs | 34 +++-- backend/server/src/models/auth.rs | 3 + backend/server/src/models/storage.rs | 2 +- backend/server/src/models/user.rs | 142 +++++++++++++++++- 8 files changed, 255 insertions(+), 15 deletions(-) create mode 100644 backend/server/src/handler/user.rs diff --git a/backend/migrations/20240406023149_create_users.sql b/backend/migrations/20240406023149_create_users.sql index f862c0da2..8dc86bf3a 100644 --- a/backend/migrations/20240406023149_create_users.sql +++ b/backend/migrations/20240406023149_create_users.sql @@ -5,6 +5,8 @@ CREATE TABLE users ( email TEXT NOT NULL UNIQUE, zid TEXT, name TEXT NOT NULL, + pronouns TEXT NOT NULL, + gender TEXT NOT NULL, degree_name TEXT, degree_starting_year INTEGER, role user_role NOT NULL, diff --git a/backend/server/src/handler/mod.rs b/backend/server/src/handler/mod.rs index 3273c2a70..e0a5a8f69 100644 --- a/backend/server/src/handler/mod.rs +++ b/backend/server/src/handler/mod.rs @@ -1,5 +1,6 @@ pub mod auth; +pub mod user; pub mod campaign; pub mod organisation; pub mod role; -pub mod application; \ No newline at end of file +pub mod application; diff --git a/backend/server/src/handler/user.rs b/backend/server/src/handler/user.rs new file mode 100644 index 000000000..4909ba910 --- /dev/null +++ b/backend/server/src/handler/user.rs @@ -0,0 +1,77 @@ +use crate::models::app::AppState; +use crate::models::auth::AuthUser; +use crate::models::error::ChaosError; +use axum::extract::{Json, State}; +use axum::http::StatusCode; +use axum::response::IntoResponse; +use crate::models::user::{User, UserDegree, UserGender, UserName, UserPronouns, UserZid}; + +pub struct UserHandler; + +impl UserHandler { + pub async fn get( + State(state): State, + user: AuthUser, + ) -> Result { + let user = User::get(user.user_id, &state.db).await?; + Ok((StatusCode::OK, Json(user))) + } + + pub async fn update_name( + State(state): State, + user: AuthUser, + Json(request_body): Json, + ) -> Result { + User::update_name(user.user_id, request_body.name, &state.db).await?; + + Ok((StatusCode::OK, "Updated username")) + } + + pub async fn update_pronouns( + State(state): State, + user: AuthUser, + Json(request_body): Json, + ) -> Result { + User::update_pronouns(user.user_id, request_body.pronouns, &state.db).await?; + + Ok((StatusCode::OK, "Updated pronouns")) + } + + pub async fn update_gender( + State(state): State, + user: AuthUser, + Json(request_body): Json, + ) -> Result { + User::update_gender(user.user_id, request_body.gender, &state.db).await?; + + Ok((StatusCode::OK, "Updated gender")) + } + + pub async fn update_zid( + State(state): State, + user: AuthUser, + Json(request_body): Json, + ) -> Result { + User::update_zid(user.user_id, request_body.zid, &state.db).await?; + + Ok((StatusCode::OK, "Updated zid")) + } + + pub async fn update_degree( + State(state): State, + user: AuthUser, + Json(request_body): Json, + ) -> Result { + User::update_degree( + user.user_id, + request_body.degree_name, + request_body.degree_starting_year, + &state.db + ) + .await?; + + Ok((StatusCode::OK, "Updated user degree")) + } +} + + diff --git a/backend/server/src/main.rs b/backend/server/src/main.rs index d2a0618c6..a0a7eaacc 100644 --- a/backend/server/src/main.rs +++ b/backend/server/src/main.rs @@ -1,4 +1,5 @@ use crate::handler::auth::google_callback; +use handler::user::UserHandler; use crate::handler::campaign::CampaignHandler; use crate::handler::organisation::OrganisationHandler; use crate::handler::application::ApplicationHandler; @@ -67,6 +68,12 @@ async fn main() -> Result<()> { let app = Router::new() .route("/", get(|| async { "Hello, World!" })) .route("/api/auth/callback/google", get(google_callback)) + .route("/api/v1/user", get(UserHandler::get)) + .route("/api/v1/user/name", patch(UserHandler::update_name)) + .route("/api/v1/user/pronouns", patch(UserHandler::update_pronouns)) + .route("/api/v1/user/gender", patch(UserHandler::update_gender)) + .route("/api/v1/user/zid", patch(UserHandler::update_zid)) + .route("/api/v1/user/degree", patch(UserHandler::update_degree)) .route( "/api/v1/user/applications", get(ApplicationHandler::get_from_curr_user), diff --git a/backend/server/src/models/application.rs b/backend/server/src/models/application.rs index da002b22c..65e55d217 100644 --- a/backend/server/src/models/application.rs +++ b/backend/server/src/models/application.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use snowflake::SnowflakeIdGenerator; use sqlx::{FromRow, Pool, Postgres, Transaction}; use std::ops::DerefMut; -use crate::models::user::User; +use crate::models::user::UserDetails; #[derive(Deserialize, Serialize, Clone, FromRow, Debug)] pub struct Application { @@ -38,7 +38,7 @@ pub struct NewApplication { pub struct ApplicationDetails { pub id: i64, pub campaign_id: i64, - pub user: User, + pub user: UserDetails, pub status: ApplicationStatus, pub private_status: ApplicationStatus, pub applied_roles: Vec @@ -52,6 +52,8 @@ pub struct ApplicationData { pub user_email: String, pub user_zid: Option, pub user_name: String, + pub user_pronouns: String, + pub user_gender: String, pub user_degree_name: Option, pub user_degree_starting_year: Option, pub status: ApplicationStatus, @@ -122,7 +124,8 @@ impl Application { " SELECT a.id AS id, campaign_id, user_id, status AS \"status: ApplicationStatus\", private_status AS \"private_status: ApplicationStatus\", u.email AS user_email, - u.zid AS user_zid, u.name AS user_name, u.degree_name AS user_degree_name, + u.zid AS user_zid, u.name AS user_name, u.gender AS user_gender, + u.pronouns AS user_pronouns, u.degree_name AS user_degree_name, u.degree_starting_year AS user_degree_starting_year FROM applications a LEFT JOIN users u ON u.id = a.user_id WHERE a.id = $1 @@ -153,11 +156,13 @@ impl Application { status: application_data.status, private_status: application_data.private_status, applied_roles, - user: User { + user: UserDetails { id: application_data.user_id, email: application_data.user_email, zid: application_data.user_zid, name: application_data.user_name, + pronouns: application_data.user_pronouns, + gender: application_data.user_gender, degree_name: application_data.user_degree_name, degree_starting_year: application_data.user_degree_starting_year, }, @@ -176,7 +181,8 @@ impl Application { " SELECT a.id AS id, campaign_id, user_id, status AS \"status: ApplicationStatus\", private_status AS \"private_status: ApplicationStatus\", u.email AS user_email, - u.zid AS user_zid, u.name AS user_name, u.degree_name AS user_degree_name, + u.zid AS user_zid, u.name AS user_name, u.gender AS user_gender, + u.pronouns AS user_pronouns, u.degree_name AS user_degree_name, u.degree_starting_year AS user_degree_starting_year FROM applications a LEFT JOIN users u ON u.id = a.user_id LEFT JOIN application_roles ar on ar.application_id = a.id WHERE ar.id = $1 @@ -208,11 +214,13 @@ impl Application { status: application_data.status, private_status: application_data.private_status, applied_roles, - user: User { + user: UserDetails { id: application_data.user_id, email: application_data.user_email, zid: application_data.user_zid, name: application_data.user_name, + pronouns: application_data.user_pronouns, + gender: application_data.user_gender, degree_name: application_data.user_degree_name, degree_starting_year: application_data.user_degree_starting_year, }, @@ -234,7 +242,8 @@ impl Application { " SELECT a.id AS id, campaign_id, user_id, status AS \"status: ApplicationStatus\", private_status AS \"private_status: ApplicationStatus\", u.email AS user_email, - u.zid AS user_zid, u.name AS user_name, u.degree_name AS user_degree_name, + u.zid AS user_zid, u.name AS user_name, u.gender AS user_gender, + u.pronouns AS user_pronouns, u.degree_name AS user_degree_name, u.degree_starting_year AS user_degree_starting_year FROM applications a LEFT JOIN users u ON u.id = a.user_id WHERE a.campaign_id = $1 @@ -266,11 +275,13 @@ impl Application { status: application_data.status, private_status: application_data.private_status, applied_roles, - user: User { + user: UserDetails { id: application_data.user_id, email: application_data.user_email, zid: application_data.user_zid, name: application_data.user_name, + pronouns: application_data.user_pronouns, + gender: application_data.user_gender, degree_name: application_data.user_degree_name, degree_starting_year: application_data.user_degree_starting_year, }, @@ -292,7 +303,8 @@ impl Application { " SELECT a.id AS id, campaign_id, user_id, status AS \"status: ApplicationStatus\", private_status AS \"private_status: ApplicationStatus\", u.email AS user_email, - u.zid AS user_zid, u.name AS user_name, u.degree_name AS user_degree_name, + u.zid AS user_zid, u.name AS user_name, u.gender AS user_gender, + u.pronouns AS user_pronouns, u.degree_name AS user_degree_name, u.degree_starting_year AS user_degree_starting_year FROM applications a LEFT JOIN users u ON u.id = a.user_id WHERE a.user_id = $1 @@ -324,11 +336,13 @@ impl Application { status: application_data.status, private_status: application_data.private_status, applied_roles, - user: User { + user: UserDetails { id: application_data.user_id, email: application_data.user_email, zid: application_data.user_zid, name: application_data.user_name, + pronouns: application_data.user_pronouns, + gender: application_data.user_gender, degree_name: application_data.user_degree_name, degree_starting_year: application_data.user_degree_starting_year, }, diff --git a/backend/server/src/models/auth.rs b/backend/server/src/models/auth.rs index c120284a7..9e1fc0403 100644 --- a/backend/server/src/models/auth.rs +++ b/backend/server/src/models/auth.rs @@ -14,6 +14,7 @@ use axum::{async_trait, RequestPartsExt}; use axum_extra::{headers::Cookie, TypedHeader}; use serde::{Deserialize, Serialize}; +// tells the web framework how to take the url query params they will have #[derive(Deserialize, Serialize)] pub struct AuthRequest { pub code: String, @@ -39,6 +40,8 @@ pub struct AuthUser { pub user_id: i64, } +// extractor - takes a request, and we define what we do to it, +// returns the struct of the type defined #[async_trait] impl FromRequestParts for AuthUser where diff --git a/backend/server/src/models/storage.rs b/backend/server/src/models/storage.rs index a94c6deaf..d44b35aaf 100644 --- a/backend/server/src/models/storage.rs +++ b/backend/server/src/models/storage.rs @@ -1,6 +1,6 @@ use crate::models::error::ChaosError; use s3::creds::Credentials; -use s3::{Bucket, BucketConfiguration, Region}; +use s3::{Bucket, Region}; use std::env; pub struct Storage; diff --git a/backend/server/src/models/user.rs b/backend/server/src/models/user.rs index f91e9ce7d..19009a1f0 100644 --- a/backend/server/src/models/user.rs +++ b/backend/server/src/models/user.rs @@ -1,4 +1,6 @@ use serde::{Deserialize, Serialize}; +use sqlx::{FromRow, Pool, Postgres}; +use crate::models::error::ChaosError; #[derive(Deserialize, Serialize, sqlx::Type, Clone)] #[sqlx(type_name = "user_role", rename_all = "PascalCase")] @@ -7,13 +9,147 @@ pub enum UserRole { SuperUser, } -// Placeholder until User CRUD is merged -#[derive(Deserialize, Serialize)] +#[derive(Deserialize, Serialize, FromRow)] +pub struct UserDetails { + pub id: i64, + pub email: String, + pub zid: Option, + pub name: String, + pub pronouns: String, + pub gender: String, + pub degree_name: Option, + pub degree_starting_year: Option, +} + +#[derive(Deserialize, Serialize, FromRow)] pub struct User { pub id: i64, pub email: String, pub zid: Option, pub name: String, + pub pronouns: String, + pub gender: String, pub degree_name: Option, pub degree_starting_year: Option, -} \ No newline at end of file + pub role: UserRole, +} + +#[derive(Deserialize, Serialize)] +pub struct UserName { + pub name: String, +} + +#[derive(Deserialize, Serialize)] +pub struct UserPronouns { + pub pronouns: String, +} + +#[derive(Deserialize, Serialize)] +pub struct UserGender { + pub gender: String, +} + +#[derive(Deserialize, Serialize)] +pub struct UserZid { + pub zid: String, +} + +#[derive(Deserialize, Serialize)] +pub struct UserDegree { + pub degree_name: String, + pub degree_starting_year: i32, +} + +impl User { + pub async fn get(id: i64, pool: &Pool) -> Result { + let user = sqlx::query_as!( + User, + r#" + SELECT id, email, zid, name, pronouns, gender, degree_name, + degree_starting_year, role AS "role!: UserRole" + FROM users WHERE id = $1 + "#, + id + ) + .fetch_one(pool) + .await?; + + Ok(user) + } + + pub async fn update_name(id: i64, name: String, pool: &Pool) -> Result<(), ChaosError> { + let _ = sqlx::query!( + " + UPDATE users SET name = $1 WHERE id = $2 RETURNING id + ", + name, + id + ) + .fetch_one(pool) + .await?; + + Ok(()) + } + + pub async fn update_pronouns(id: i64, pronouns: String, pool: &Pool) -> Result<(), ChaosError> { + let _ = sqlx::query!( + " + UPDATE users SET pronouns = $1 WHERE id = $2 RETURNING id + ", + pronouns, + id + ) + .fetch_one(pool) + .await?; + + Ok(()) + } + + pub async fn update_gender(id: i64, gender: String, pool: &Pool) -> Result<(), ChaosError> { + let _ = sqlx::query!( + " + UPDATE users SET gender = $1 WHERE id = $2 RETURNING id + ", + gender, + id + ) + .fetch_one(pool) + .await?; + + Ok(()) + } + + pub async fn update_zid(id: i64, zid: String, pool: &Pool) -> Result<(), ChaosError> { + let _ = sqlx::query!( + " + UPDATE users SET zid = $1 WHERE id = $2 RETURNING id + ", + zid, + id + ) + .fetch_one(pool) + .await?; + + Ok(()) + } + + pub async fn update_degree( + id: i64, + degree_name: String, + degree_starting_year: i32, + pool: &Pool, + ) -> Result<(), ChaosError> { + let _ = sqlx::query!( + " + UPDATE users SET degree_name = $1, degree_starting_year = $2 WHERE id = $3 RETURNING id + ", + degree_name, + degree_starting_year, + id + ) + .fetch_one(pool) + .await?; + + Ok(()) + } +} From 15aa828bedc6898060cee4a02fef6a60a8b33fb3 Mon Sep 17 00:00:00 2001 From: Fritz Rehde Date: Fri, 2 Aug 2024 16:20:22 +1000 Subject: [PATCH 32/56] feat(backend): improved error handling for dev env setup script (#500) --- backend/setup-dev-env.sh | 68 ++++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/backend/setup-dev-env.sh b/backend/setup-dev-env.sh index d7257648c..0eaa03a0e 100755 --- a/backend/setup-dev-env.sh +++ b/backend/setup-dev-env.sh @@ -5,33 +5,10 @@ # backend can only be built and run if the database is also running, due to # sqlx. -# Create .env file. -env_file=.env -if [ -f "$env_file" ]; then - while true; do - printf "You already have a $env_file file, are you sure you want to continue, as this will override your $env_file file? [yn] " - read -r answer - case "$answer" in - y) - # Continue with execution. - break - ;; - n) - echo "Aborting" - exit 0 - ;; - *) - # Try again. - echo "Invalid answer. Please type either 'y' for yes, or 'n' for no." - continue - ;; - esac - done -fi - -echo "Overwriting $env_file file" - -cat << 'EOF' > "$env_file" +# Write .env file to temporary file. +tmp_env_file="$(mktemp)" +trap 'rm -rf "$tmp_env_file"' EXIT INT TERM +cat << 'EOF' > "$tmp_env_file" DATABASE_URL="postgres://user:password@localhost:5432/chaos" JWT_SECRET="test_secret" GOOGLE_CLIENT_ID="test" @@ -44,6 +21,35 @@ S3_ENDPOINT="https://chaos-storage.s3.ap-southeast-1.amazonaws.com" S3_REGION_NAME="ap-southeast-1" EOF +# Check the user has all required tools installed. +for cmd in "which cargo" "which docker && docker info" "which docker-compose || docker compose"; do + if ! eval "$cmd" 1>/dev/null 2>&1; then + echo "The command '$cmd' failed, indicating you might not have that tool installed." >&2 + exit 1 + fi +done + +# Create .env file. +env_file=.env + +# The .env file already exists. +if [ -f "$env_file" ]; then + # If existing env file differs from new one, save the existing env file to a backup file. + if ! diff "$env_file" "$tmp_env_file" > /dev/null; then + backup_env_file="$env_file" + while [ -f "$backup_env_file" ]; do + # Append `.backup` to backup filename until we find a filename that doesn't exist yet. + backup_env_file="$backup_env_file.backup" + done + + echo "Saving existing env file '$env_file' to backup env file '$backup_env_file'" + mv "$env_file" "$backup_env_file" + fi +fi + +echo "Overwriting $env_file file" +cp "$tmp_env_file" "$env_file" + # Install sqlx if it isn't installed yet. if ! which sqlx >/dev/null; then echo "Installing sqlx" @@ -58,10 +64,10 @@ docker_compose_file_name="setup-test-database.yml" docker_compose_file_path="$this_script_dir/$docker_compose_file_name" echo 'Starting up postgres database in docker' -docker-compose -f "$docker_compose_file_path" up --detach +docker-compose -f "$docker_compose_file_path" up --detach || exit 1 # Ensure the docker container gets killed once this script exits. -trap 'echo "shutting down $docker_compose_file_path" && docker-compose -f "$docker_compose_file_path" down' EXIT +trap 'echo "shutting down $docker_compose_file_path" && docker-compose -f "$docker_compose_file_path" down' EXIT INT TERM # Wait for the database to be ready. echo "Waiting for database to be ready" @@ -69,7 +75,7 @@ sleep 3 # Setup sqlx. echo "Setting up sqlx" -sqlx database create -sqlx migrate run +sqlx database create || exit 1 +sqlx migrate run || exit 1 "$SHELL" From f1994a7cd49f05ea51858af5d2fd5a4d1ec52d3b Mon Sep 17 00:00:00 2001 From: Kavika Date: Tue, 5 Nov 2024 21:05:20 +1100 Subject: [PATCH 33/56] Question types framework + ShortAnswer & MultiChoice implementations (#483) * Move initial migration to one file * Update initial schema NOT NULL columns * Fix question_id ref column being int not bigint * Question framework and impl for MultiOption and ShortAnswer * answer framework for short answer and multichoice * update `Question` documentation to fit `serde` representation * fix duplicates in question framework * remove redundancy in answer framework * make question option id unique snowflake * re-separate schema migrations * set timestamps fields to `NOT NULL` * add answer to models module file * fix enum errors * fix always true/false case in answer length * add `Ranking` question type * rename multi option data "rank" to "order" * update question json example * fix use of postgres keyword `order` --------- Co-authored-by: skye_blair --- .../20240406023149_create_users.sql | 6 +- .../20240406024211_create_organisations.sql | 7 +- .../20240406025537_create_campaigns.sql | 18 +-- .../20240406031400_create_questions.sql | 22 +-- .../20240406031915_create_applications.sql | 57 +++++--- backend/server/src/models/answer.rs | 110 +++++++++++++++ backend/server/src/models/mod.rs | 3 + backend/server/src/models/question.rs | 128 ++++++++++++++++++ 8 files changed, 306 insertions(+), 45 deletions(-) create mode 100644 backend/server/src/models/answer.rs create mode 100644 backend/server/src/models/question.rs diff --git a/backend/migrations/20240406023149_create_users.sql b/backend/migrations/20240406023149_create_users.sql index 8dc86bf3a..b820e2d2b 100644 --- a/backend/migrations/20240406023149_create_users.sql +++ b/backend/migrations/20240406023149_create_users.sql @@ -10,8 +10,8 @@ CREATE TABLE users ( degree_name TEXT, degree_starting_year INTEGER, role user_role NOT NULL, - created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL, - updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL + created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP ); -CREATE UNIQUE INDEX IDX_users_email_lower on users ((lower(email))); +CREATE UNIQUE INDEX IDX_users_email_lower on users ((lower(email))); \ No newline at end of file diff --git a/backend/migrations/20240406024211_create_organisations.sql b/backend/migrations/20240406024211_create_organisations.sql index 24f2c18d9..008777c16 100644 --- a/backend/migrations/20240406024211_create_organisations.sql +++ b/backend/migrations/20240406024211_create_organisations.sql @@ -2,8 +2,8 @@ CREATE TABLE organisations ( id BIGINT PRIMARY KEY, name TEXT NOT NULL UNIQUE, logo UUID, - created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL, - updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL + created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP ); CREATE TYPE organisation_role AS ENUM ('User', 'Admin'); @@ -12,7 +12,7 @@ CREATE TABLE organisation_members ( id BIGSERIAL PRIMARY KEY, organisation_id BIGINT NOT NULL, user_id BIGINT NOT NULL, - role organisation_role DEFAULT 'User' NOT NULL, + role organisation_role NOT NULL DEFAULT 'User', CONSTRAINT FK_organisation_members_organisation FOREIGN KEY(organisation_id) REFERENCES organisations(id) @@ -20,4 +20,5 @@ CREATE TABLE organisation_members ( ON UPDATE CASCADE ); + CREATE INDEX IDX_organisation_admins_organisation on organisation_members (organisation_id); diff --git a/backend/migrations/20240406025537_create_campaigns.sql b/backend/migrations/20240406025537_create_campaigns.sql index ebc1311ca..757a3e630 100644 --- a/backend/migrations/20240406025537_create_campaigns.sql +++ b/backend/migrations/20240406025537_create_campaigns.sql @@ -6,13 +6,13 @@ CREATE TABLE campaigns ( description TEXT, starts_at TIMESTAMPTZ NOT NULL, ends_at TIMESTAMPTZ NOT NULL, - created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL, - updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL, + created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT FK_campaigns_organisations - FOREIGN KEY(organisation_id) - REFERENCES organisations(id) - ON DELETE CASCADE - ON UPDATE CASCADE + FOREIGN KEY(organisation_id) + REFERENCES organisations(id) + ON DELETE CASCADE + ON UPDATE CASCADE ); CREATE TABLE campaign_roles ( @@ -23,8 +23,8 @@ CREATE TABLE campaign_roles ( min_available INTEGER NOT NULL, max_available INTEGER NOT NULL, finalised BOOLEAN NOT NULL, - created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL, - updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL, + created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT FK_campaign_roles_campaign FOREIGN KEY(campaign_id) REFERENCES campaigns(id) @@ -32,4 +32,4 @@ CREATE TABLE campaign_roles ( ON UPDATE CASCADE ); -CREATE INDEX IDX_campaign_roles_campaign on campaign_roles (campaign_id); +CREATE INDEX IDX_campaign_roles_campaign on campaign_roles (campaign_id); \ No newline at end of file diff --git a/backend/migrations/20240406031400_create_questions.sql b/backend/migrations/20240406031400_create_questions.sql index 8e7136afe..24f01d971 100644 --- a/backend/migrations/20240406031400_create_questions.sql +++ b/backend/migrations/20240406031400_create_questions.sql @@ -1,14 +1,15 @@ -CREATE TYPE question_type AS ENUM ('ShortAnswer', 'MultiChoice', 'MultiSelect', 'DropDown'); +CREATE TYPE question_type AS ENUM ('ShortAnswer', 'MultiChoice', 'MultiSelect', 'DropDown', 'Ranking'); CREATE TABLE questions ( id BIGINT PRIMARY KEY, title TEXT NOT NULL, description TEXT, + common BOOLEAN NOT NULL, required BOOLEAN, question_type question_type NOT NULL, campaign_id BIGINT NOT NULL, - created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL, - updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL, + created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT FK_questions_campaigns FOREIGN KEY(campaign_id) REFERENCES campaigns(id) @@ -17,14 +18,15 @@ CREATE TABLE questions ( ); CREATE TABLE multi_option_question_options ( - id BIGSERIAL PRIMARY KEY, + id BIGINT PRIMARY KEY, text TEXT NOT NULL, - question_id INTEGER NOT NULL, + question_id BIGINT NOT NULL, + display_order INTEGER NOT NULL, CONSTRAINT FK_multi_option_question_options_questions - FOREIGN KEY(question_id) - REFERENCES questions(id) - ON DELETE CASCADE - ON UPDATE CASCADE + FOREIGN KEY(question_id) + REFERENCES questions(id) + ON DELETE CASCADE + ON UPDATE CASCADE ); -CREATE INDEX IDX_multi_option_question_options_questions on multi_option_question_options (question_id); +CREATE INDEX IDX_multi_option_question_options_questions on multi_option_question_options (question_id); \ No newline at end of file diff --git a/backend/migrations/20240406031915_create_applications.sql b/backend/migrations/20240406031915_create_applications.sql index e2fcd0576..7d1053b30 100644 --- a/backend/migrations/20240406031915_create_applications.sql +++ b/backend/migrations/20240406031915_create_applications.sql @@ -6,13 +6,13 @@ CREATE TABLE applications ( user_id BIGINT NOT NULL, status application_status NOT NULL DEFAULT 'Pending', private_status application_status NOT NULL DEFAULT 'Pending', - created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL, - updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL, + created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT FK_applications_campaigns - FOREIGN KEY(campaign_id) - REFERENCES campaigns(id) - ON DELETE CASCADE - ON UPDATE CASCADE, + FOREIGN KEY(campaign_id) + REFERENCES campaigns(id) + ON DELETE CASCADE + ON UPDATE CASCADE, CONSTRAINT FK_applications_users FOREIGN KEY(user_id) REFERENCES users(id) @@ -40,7 +40,7 @@ CREATE INDEX IDX_application_roles_applications on application_roles (applicatio CREATE INDEX IDX_application_roles_campaign_roles on application_roles (campaign_role_id); CREATE TABLE answers ( - id BIGSERIAL PRIMARY KEY, + id BIGINT PRIMARY KEY, application_id BIGINT NOT NULL, question_id BIGINT NOT NULL, CONSTRAINT FK_answers_applications @@ -61,7 +61,7 @@ CREATE INDEX IDX_answers_questions on answers (question_id); CREATE TABLE short_answer_answers ( id BIGSERIAL PRIMARY KEY, text TEXT NOT NULL, - answer_id INTEGER NOT NULL, + answer_id BIGINT NOT NULL, CONSTRAINT FK_short_answer_answers_answers FOREIGN KEY(answer_id) REFERENCES answers(id) @@ -74,17 +74,34 @@ CREATE INDEX IDX_short_answer_answers_answers on short_answer_answers (answer_id CREATE TABLE multi_option_answer_options ( id BIGSERIAL PRIMARY KEY, option_id BIGINT NOT NULL, - answer_id INTEGER NOT NULL, + answer_id BIGINT NOT NULL, CONSTRAINT FK_multi_option_answer_options_question_options FOREIGN KEY(option_id) REFERENCES multi_option_question_options(id) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT FK_multi_option_answer_options_answers - FOREIGN KEY(answer_id) - REFERENCES answers(id) - ON DELETE CASCADE - ON UPDATE CASCADE + FOREIGN KEY(answer_id) + REFERENCES answers(id) + ON DELETE CASCADE + ON UPDATE CASCADE +); + +CREATE TABLE ranking_answer_rankings ( + id BIGSERIAL PRIMARY KEY, + option_id BIGINT NOT NULL, + rank INTEGER NOT NULL, + answer_id BIGINT NOT NULL, + CONSTRAINT FK_ranking_answer_rankings_question_options + FOREIGN KEY(option_id) + REFERENCES multi_option_question_options(id) + ON DELETE CASCADE + ON UPDATE CASCADE, + CONSTRAINT FK_ranking_answer_rankings_answers + FOREIGN KEY(answer_id) + REFERENCES answers(id) + ON DELETE CASCADE + ON UPDATE CASCADE ); CREATE INDEX IDX_multi_option_answer_options_question_options on multi_option_answer_options (option_id); @@ -95,13 +112,13 @@ CREATE TABLE application_ratings ( application_id BIGINT NOT NULL, rater_id BIGINT NOT NULL, rating INTEGER NOT NULL, - created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL, - updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL, + created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT FK_application_ratings_applications - FOREIGN KEY(application_id) - REFERENCES applications(id) - ON DELETE CASCADE - ON UPDATE CASCADE, + FOREIGN KEY(application_id) + REFERENCES applications(id) + ON DELETE CASCADE + ON UPDATE CASCADE, CONSTRAINT FK_application_ratings_users FOREIGN KEY(rater_id) REFERENCES users(id) @@ -110,4 +127,4 @@ CREATE TABLE application_ratings ( ); CREATE INDEX IDX_application_ratings_applications on application_ratings (application_id); -CREATE INDEX IDX_application_ratings_users on application_ratings (rater_id); +CREATE INDEX IDX_application_ratings_users on application_ratings (rater_id); \ No newline at end of file diff --git a/backend/server/src/models/answer.rs b/backend/server/src/models/answer.rs new file mode 100644 index 000000000..f79bf9d6b --- /dev/null +++ b/backend/server/src/models/answer.rs @@ -0,0 +1,110 @@ +use crate::models::error::ChaosError; +use anyhow::{bail, Result}; +use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; +use sqlx::{Pool, Postgres, QueryBuilder, Row}; + +/// The `Answer` type that will be sent in API responses. +/// +/// +/// With the chosen `serde` representation and the use of `#[serde(flatten)]`, the JSON for a +/// `Answer` will look like this: +/// ```json +/// { +/// "id": 7233828375289773948, +/// "application_id": 7233828375289125398, +/// "question_id": 7233828375289139200, +/// "answer_type": "MultiChoice", +/// "data": 7233828393325384908, +/// "created_at": "2024-06-28T16:29:04.644008111Z", +/// "updated_at": "2024-06-30T12:14:12.458390190Z" +/// } +/// ``` +#[derive(Deserialize, Serialize)] +pub struct Answer { + id: i64, + application_id: i64, + question_id: i64, + + #[serde(flatten)] + answer_data: AnswerData, + + created_at: DateTime, + updated_at: DateTime, +} + +#[derive(Deserialize, Serialize)] +#[serde( tag = "answer_type", content = "data")] +pub enum AnswerData { + ShortAnswer(String), + MultiChoice(i64), + MultiSelect(Vec), + DropDown(i64), + Ranking(Vec) +} + +impl AnswerData { + pub async fn validate(self) -> Result<()> { + match self { + Self::ShortAnswer(text) => if text.len() == 0 { bail!("Empty answer") }, + Self::MultiSelect(data) => if data.len() == 0 { bail!("Empty answer") }, + _ => {}, + } + + Ok(()) + } + + pub async fn insert_into_db(self, answer_id: i64, pool: &Pool) -> Result<()> { + match self { + Self::ShortAnswer(text) => { + let result = sqlx::query!( + "INSERT INTO short_answer_answers (text, answer_id) VALUES ($1, $2)", + text, + answer_id + ) + .execute(pool) + .await?; + + Ok(()) + }, + Self::MultiChoice(option_id) + | Self::DropDown(option_id) => { + let result = sqlx::query!( + "INSERT INTO multi_option_answer_options (option_id, answer_id) VALUES ($1, $2)", + option_id, + answer_id + ) + .execute(pool) + .await?; + + Ok(()) + }, + Self::MultiSelect(option_ids) => { + let mut query_builder = sqlx::QueryBuilder::new("INSERT INTO multi_option_answer_options (option_id, answer_id)"); + + query_builder.push_values(option_ids, |mut b, option_id| { + b.push_bind(option_id).push_bind(answer_id); + }); + + let query = query_builder.build(); + let result = query.execute(pool).await?; + + Ok(()) + }, + Self::Ranking(option_ids) => { + let mut query_builder = sqlx::QueryBuilder::new("INSERT INTO ranking_answer_rankings (option_id, rank, answer_id)"); + + let mut rank = 1; + query_builder.push_values(option_ids, |mut b, option_id| { + b.push_bind(option_id).push_bind(rank).push_bind(answer_id); + rank += 1; + }); + + let query = query_builder.build(); + let result = query.execute(pool).await?; + + Ok(()) + } + } + } +} diff --git a/backend/server/src/models/mod.rs b/backend/server/src/models/mod.rs index 0af7da1a7..bb79ea9d0 100644 --- a/backend/server/src/models/mod.rs +++ b/backend/server/src/models/mod.rs @@ -1,10 +1,13 @@ +pub mod answer; pub mod app; pub mod auth; pub mod campaign; pub mod error; +pub mod question; pub mod organisation; pub mod role; pub mod storage; pub mod transaction; pub mod user; pub mod application; + diff --git a/backend/server/src/models/question.rs b/backend/server/src/models/question.rs new file mode 100644 index 000000000..307a7aae7 --- /dev/null +++ b/backend/server/src/models/question.rs @@ -0,0 +1,128 @@ +use crate::models::error::ChaosError; +use anyhow::{bail, Result}; +use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; +use sqlx::{Pool, Postgres, QueryBuilder, Row}; +use snowflake::SnowflakeIdGenerator; + +/// The `Question` type that will be sent in API responses. +/// +/// +/// With the chosen `serde` representation and the use of `#[serde(flatten)]`, the JSON for a +/// `Question` will look like this: +/// ```json +/// { +/// "id": 7233828375289139200, +/// "title": "What is your favourite language?", +/// "required": true, +/// "question_type": "MultiChoice", +/// "data": { +/// "options": [ +/// { +/// "id": 7233828375387640938, +/// "display_order": 1, +/// "text": "Rust" +/// }, +/// { +/// "id": 7233828375387640954, +/// "display_order": 2, +/// "text": "Java" +/// }, +/// { +/// "id": 7233828375387640374, +/// "display_order": 3, +/// "text": "TypeScript" +/// } +/// ] +/// }, +/// "created_at": "2024-06-28T16:29:04.644008111Z", +/// "updated_at": "2024-06-30T12:14:12.458390190Z" +/// } +/// ``` +#[derive(Serialize)] +pub struct Question { + id: i64, + title: String, + description: Option, + common: bool, // Common question are shown at the start + required: bool, + + #[serde(flatten)] + question_data: QuestionData, + + created_at: DateTime, + updated_at: DateTime, +} + +/// An enum that represents all the data types of question data that CHAOS can handle. +/// This stores all the data for each question type. +/// +/// \ +/// Some question types are stored in memory and JSON using the same struct, and only differ +/// in their implementation when inserting to the database and in their restrictions +/// (e.g. max 1 answer allowed in multi-choice vs. many in multi-select) +#[derive(Deserialize, Serialize)] +#[serde(tag = "question_type", content = "data")] +pub enum QuestionData { + ShortAnswer, + MultiChoice(MultiOptionData), + MultiSelect(MultiOptionData), + DropDown(MultiOptionData), + Ranking(MultiOptionData), +} + +#[derive(Deserialize, Serialize)] +pub struct MultiOptionData { + options: Vec, +} + +/// Each of these structs represent a row in the `multi_option_question_options` +/// table. For a `MultiChoice` question like "What is your favourite programming +/// language?", there would be rows for "Rust", "Java" and "TypeScript". +#[derive(Deserialize, Serialize)] +pub struct MultiOptionQuestionOption { + id: i32, + display_order: i32, + text: String, +} + +impl QuestionData { + pub async fn validate(self) -> Result<()> { + match self { + Self::ShortAnswer => Ok(()), + Self::MultiChoice(data) + | Self::MultiSelect(data) + | Self::DropDown(data) + | Self::Ranking(data) => { + if data.options.len() > 0 { + return Ok(()); + }; + + bail!("Invalid number of options.") + } + } + } + + pub async fn insert_into_db(self, question_id: i64, pool: &Pool, mut snowflake_generator: SnowflakeIdGenerator) -> Result<()> { + match self { + Self::ShortAnswer => Ok(()), + Self::MultiChoice(data) + | Self::MultiSelect(data) + | Self::DropDown(data) + | Self::Ranking(data) => { + let mut query_builder = + QueryBuilder::new("INSERT INTO multi_option_question_options (id, text, question_id, display_order)"); + + query_builder.push_values(data.options, |mut b, option| { + let id = snowflake_generator.real_time_generate(); + b.push_bind(id).push_bind(option.text).push_bind(question_id).push_bind(option.display_order); + }); + + let query = query_builder.build(); + let result = query.execute(pool).await?; + + Ok(()) + } + } + } +} From 47aef321e3a9de2be7b1a2eefe1d03e8f98a2f71 Mon Sep 17 00:00:00 2001 From: Fritz Rehde Date: Tue, 12 Nov 2024 18:22:42 +1100 Subject: [PATCH 34/56] Ratings CRUD (#516) * feat(backend): ratings CRUD draft * backend: added auth to ratings CRUD * implemented most feedback * fixed ratings authorisation * fixed create rating authorisation * Update .gitignore * add optional `comment` to rating * removed redundant authorisation service * renamed RatingCreatorAdmin * remove "Admin" from some AuthZ models * fix merge error * use `ChaosError` for Question and Answer functions * Update Cargo.toml * Revert "Update Cargo.toml" This reverts commit 9a8c7b79f268eea5031a33f185c11846a9c13560. --------- Co-authored-by: Kavika --- backend/.gitignore | 3 +- .../20240406031915_create_applications.sql | 7 +- backend/server/src/handler/mod.rs | 1 + backend/server/src/handler/ratings.rs | 81 ++++++++ backend/server/src/main.rs | 15 ++ backend/server/src/models/answer.rs | 9 +- backend/server/src/models/auth.rs | 182 +++++++++++++++++- backend/server/src/models/mod.rs | 1 + backend/server/src/models/question.rs | 7 +- backend/server/src/models/ratings.rs | 157 +++++++++++++++ backend/server/src/service/mod.rs | 1 + backend/server/src/service/organisation.rs | 2 +- backend/server/src/service/ratings.rs | 125 ++++++++++++ 13 files changed, 575 insertions(+), 16 deletions(-) create mode 100644 backend/server/src/handler/ratings.rs create mode 100644 backend/server/src/models/ratings.rs create mode 100644 backend/server/src/service/ratings.rs diff --git a/backend/.gitignore b/backend/.gitignore index 5d9dc7ef4..876a49bb1 100644 --- a/backend/.gitignore +++ b/backend/.gitignore @@ -2,4 +2,5 @@ target Cargo.lock prisma-cli/prisma/migrations -/.idea \ No newline at end of file +/.idea +.DS_Store \ No newline at end of file diff --git a/backend/migrations/20240406031915_create_applications.sql b/backend/migrations/20240406031915_create_applications.sql index 7d1053b30..1adf0d9cf 100644 --- a/backend/migrations/20240406031915_create_applications.sql +++ b/backend/migrations/20240406031915_create_applications.sql @@ -108,12 +108,13 @@ CREATE INDEX IDX_multi_option_answer_options_question_options on multi_option_an CREATE INDEX IDX_multi_option_answer_options_answers on multi_option_answer_options (answer_id); CREATE TABLE application_ratings ( - id BIGSERIAL PRIMARY KEY, + id BIGINT PRIMARY KEY, application_id BIGINT NOT NULL, rater_id BIGINT NOT NULL, rating INTEGER NOT NULL, - created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, + comment TEXT, + created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL, + updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL, CONSTRAINT FK_application_ratings_applications FOREIGN KEY(application_id) REFERENCES applications(id) diff --git a/backend/server/src/handler/mod.rs b/backend/server/src/handler/mod.rs index e0a5a8f69..c577af3ec 100644 --- a/backend/server/src/handler/mod.rs +++ b/backend/server/src/handler/mod.rs @@ -2,5 +2,6 @@ pub mod auth; pub mod user; pub mod campaign; pub mod organisation; +pub mod ratings; pub mod role; pub mod application; diff --git a/backend/server/src/handler/ratings.rs b/backend/server/src/handler/ratings.rs new file mode 100644 index 000000000..d8d6071f0 --- /dev/null +++ b/backend/server/src/handler/ratings.rs @@ -0,0 +1,81 @@ +use crate::models::app::AppState; +use crate::models::auth::{ + ApplicationCreatorGivenApplicationId, ApplicationReviewerGivenApplicationId, + ApplicationReviewerGivenRatingId, RatingCreator, SuperUser, +}; +use crate::models::error::ChaosError; +use crate::models::ratings::{NewRating, Rating}; +use crate::models::transaction::DBTransaction; +use axum::extract::{Json, Path, State}; +use axum::http::StatusCode; +use axum::response::IntoResponse; + +pub struct RatingsHandler; + +impl RatingsHandler { + // TODO: are all the user permissions as required? Who should be able to do what with ratings? + pub async fn create_rating( + State(state): State, + Path(application_id): Path, + _admin: ApplicationCreatorGivenApplicationId, + mut transaction: DBTransaction<'_>, + Json(new_rating): Json, + ) -> Result { + Rating::create( + new_rating, + application_id, + state.snowflake_generator, + &mut transaction.tx, + ) + .await?; + transaction.tx.commit().await?; + Ok((StatusCode::OK, "Successfully created rating")) + } + + pub async fn update( + State(_state): State, + Path(rating_id): Path, + _admin: RatingCreator, + mut transaction: DBTransaction<'_>, + Json(updated_rating): Json, + ) -> Result { + Rating::update(rating_id, updated_rating, &mut transaction.tx).await?; + transaction.tx.commit().await?; + Ok((StatusCode::OK, "Successfully updated rating")) + } + + pub async fn get_ratings_for_application( + State(_state): State, + Path(application_id): Path, + _admin: ApplicationReviewerGivenApplicationId, + mut transaction: DBTransaction<'_>, + ) -> Result { + let ratings = + Rating::get_all_ratings_from_application_id(application_id, &mut transaction.tx) + .await?; + transaction.tx.commit().await?; + Ok((StatusCode::OK, Json(ratings))) + } + + pub async fn get( + State(_state): State, + Path(rating_id): Path, + _admin: ApplicationReviewerGivenRatingId, + mut transaction: DBTransaction<'_>, + ) -> Result { + let org = Rating::get_rating(rating_id, &mut transaction.tx).await?; + transaction.tx.commit().await?; + Ok((StatusCode::OK, Json(org))) + } + + pub async fn delete( + State(_state): State, + Path(rating_id): Path, + _admin: ApplicationReviewerGivenRatingId, + mut transaction: DBTransaction<'_>, + ) -> Result { + Rating::delete(rating_id, &mut transaction.tx).await?; + transaction.tx.commit().await?; + Ok((StatusCode::OK, "Successfully deleted rating")) + } +} diff --git a/backend/server/src/main.rs b/backend/server/src/main.rs index a0a7eaacc..1acdfa515 100644 --- a/backend/server/src/main.rs +++ b/backend/server/src/main.rs @@ -7,6 +7,7 @@ use crate::models::storage::Storage; use anyhow::Result; use axum::routing::{get, patch, post}; use axum::Router; +use handler::ratings::RatingsHandler; use handler::role::RoleHandler; use jsonwebtoken::{Algorithm, DecodingKey, EncodingKey, Header, Validation}; use models::app::AppState; @@ -107,6 +108,20 @@ async fn main() -> Result<()> { .put(OrganisationHandler::update_admins) .delete(OrganisationHandler::remove_admin), ) + .route( + "/api/v1/ratings/:rating_id", + get(RatingsHandler::get) + .delete(RatingsHandler::delete) + .put(RatingsHandler::update), + ) + .route( + "/api/v1/:application_id/rating", + post(RatingsHandler::create_rating), + ) + .route( + "/api/v1/:application_id/ratings", + get(RatingsHandler::get_ratings_for_application), + ) .route( "/api/v1/campaign/:campaign_id/role", post(CampaignHandler::create_role), diff --git a/backend/server/src/models/answer.rs b/backend/server/src/models/answer.rs index f79bf9d6b..b892fc18a 100644 --- a/backend/server/src/models/answer.rs +++ b/backend/server/src/models/answer.rs @@ -1,5 +1,4 @@ use crate::models::error::ChaosError; -use anyhow::{bail, Result}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use sqlx::{Pool, Postgres, QueryBuilder, Row}; @@ -44,17 +43,17 @@ pub enum AnswerData { } impl AnswerData { - pub async fn validate(self) -> Result<()> { + pub async fn validate(self) -> Result<(), ChaosError> { match self { - Self::ShortAnswer(text) => if text.len() == 0 { bail!("Empty answer") }, - Self::MultiSelect(data) => if data.len() == 0 { bail!("Empty answer") }, + Self::ShortAnswer(text) => if text.len() == 0 { return Err(ChaosError::BadRequest) }, + Self::MultiSelect(data) => if data.len() == 0 { return Err(ChaosError::BadRequest) }, _ => {}, } Ok(()) } - pub async fn insert_into_db(self, answer_id: i64, pool: &Pool) -> Result<()> { + pub async fn insert_into_db(self, answer_id: i64, pool: &Pool) -> Result<(), ChaosError> { match self { Self::ShortAnswer(text) => { let result = sqlx::query!( diff --git a/backend/server/src/models/auth.rs b/backend/server/src/models/auth.rs index 9e1fc0403..89e822775 100644 --- a/backend/server/src/models/auth.rs +++ b/backend/server/src/models/auth.rs @@ -5,7 +5,11 @@ use crate::service::application::user_is_application_admin; use crate::service::auth::is_super_user; use crate::service::campaign::user_is_campaign_admin; use crate::service::jwt::decode_auth_token; -use crate::service::organisation::user_is_organisation_admin; +use crate::service::organisation::assert_user_is_organisation_admin; +use crate::service::ratings::{ + assert_user_is_application_reviewer_given_rating_id, assert_user_is_organisation_member, + assert_user_is_rating_creator_and_organisation_member, +}; use crate::service::role::user_is_role_admin; use axum::extract::{FromRef, FromRequestParts, Path}; use axum::http::request::Parts; @@ -148,7 +152,7 @@ where .get("organisation_id") .ok_or(ChaosError::BadRequest)?; - user_is_organisation_admin(user_id, organisation_id, pool).await?; + assert_user_is_organisation_admin(user_id, organisation_id, pool).await?; Ok(OrganisationAdmin { user_id }) } @@ -277,3 +281,177 @@ where Ok(ApplicationAdmin { user_id }) } } + +// TODO: Not very idiomatic way. The reason this impl was chosen was because we +// couldn't figure out how to dynamically check whether the id passed in path +// was a rating id or an application id. + +// TODO: there is currently no diff between ApplicationReviewerAdminGivenApplicationId +// and ApplicationCreatorAdminGivenApplicationId, but that might change, so separating just in case. + +/// Get the application reviewer given a path that contains the application id. +pub struct ApplicationReviewerGivenApplicationId { + pub user_id: i64, +} + +#[async_trait] +impl FromRequestParts for ApplicationReviewerGivenApplicationId +where + AppState: FromRef, + S: Send + Sync, +{ + type Rejection = ChaosError; + + async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { + // TODO: put into separate function, since this is just getting the id through jwt, and duplicated here. + let app_state = AppState::from_ref(state); + let decoding_key = &app_state.decoding_key; + let jwt_validator = &app_state.jwt_validator; + let TypedHeader(cookies) = parts + .extract::>() + .await + .map_err(|_| ChaosError::NotLoggedIn)?; + + let token = cookies.get("auth_token").ok_or(ChaosError::NotLoggedIn)?; + + let claims = + decode_auth_token(token, decoding_key, jwt_validator).ok_or(ChaosError::NotLoggedIn)?; + + let pool = &app_state.db; + let user_id = claims.sub; + + let Path(application_id) = parts + .extract::>() + .await + .map_err(|_| ChaosError::BadRequest)?; + + assert_user_is_organisation_member(user_id, application_id, pool).await?; + + Ok(ApplicationReviewerGivenApplicationId { user_id }) + } +} + +/// Get the application reviewer given a path that contains the application id. +pub struct ApplicationCreatorGivenApplicationId { + pub user_id: i64, +} + +#[async_trait] +impl FromRequestParts for ApplicationCreatorGivenApplicationId +where + AppState: FromRef, + S: Send + Sync, +{ + type Rejection = ChaosError; + + async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { + // TODO: put into separate function, since this is just getting the id through jwt, and duplicated here. + let app_state = AppState::from_ref(state); + let decoding_key = &app_state.decoding_key; + let jwt_validator = &app_state.jwt_validator; + let TypedHeader(cookies) = parts + .extract::>() + .await + .map_err(|_| ChaosError::NotLoggedIn)?; + + let token = cookies.get("auth_token").ok_or(ChaosError::NotLoggedIn)?; + + let claims = + decode_auth_token(token, decoding_key, jwt_validator).ok_or(ChaosError::NotLoggedIn)?; + + let pool = &app_state.db; + let user_id = claims.sub; + + let Path(application_id) = parts + .extract::>() + .await + .map_err(|_| ChaosError::BadRequest)?; + + assert_user_is_organisation_member(user_id, application_id, pool).await?; + + Ok(ApplicationCreatorGivenApplicationId { user_id }) + } +} + +/// Get the application reviewer given a path that contains the rating id. +pub struct ApplicationReviewerGivenRatingId { + pub user_id: i64, +} + +#[async_trait] +impl FromRequestParts for ApplicationReviewerGivenRatingId +where + AppState: FromRef, + S: Send + Sync, +{ + type Rejection = ChaosError; + + async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { + // TODO: put into separate function, since this is just getting the id through jwt, and duplicated here. + let app_state = AppState::from_ref(state); + let decoding_key = &app_state.decoding_key; + let jwt_validator = &app_state.jwt_validator; + let TypedHeader(cookies) = parts + .extract::>() + .await + .map_err(|_| ChaosError::NotLoggedIn)?; + + let token = cookies.get("auth_token").ok_or(ChaosError::NotLoggedIn)?; + + let claims = + decode_auth_token(token, decoding_key, jwt_validator).ok_or(ChaosError::NotLoggedIn)?; + + let pool = &app_state.db; + let user_id = claims.sub; + + let Path(rating_id) = parts + .extract::>() + .await + .map_err(|_| ChaosError::BadRequest)?; + + assert_user_is_application_reviewer_given_rating_id(user_id, rating_id, pool).await?; + + Ok(ApplicationReviewerGivenRatingId { user_id }) + } +} + +pub struct RatingCreator { + pub user_id: i64, +} + +#[async_trait] +impl FromRequestParts for RatingCreator +where + AppState: FromRef, + S: Send + Sync, +{ + type Rejection = ChaosError; + + async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { + // TODO: put into separate function, since this is just getting the id through jwt, and duplicated here. + let app_state = AppState::from_ref(state); + let decoding_key = &app_state.decoding_key; + let jwt_validator = &app_state.jwt_validator; + let TypedHeader(cookies) = parts + .extract::>() + .await + .map_err(|_| ChaosError::NotLoggedIn)?; + + let token = cookies.get("auth_token").ok_or(ChaosError::NotLoggedIn)?; + + let claims = + decode_auth_token(token, decoding_key, jwt_validator).ok_or(ChaosError::NotLoggedIn)?; + + let pool = &app_state.db; + let user_id = claims.sub; + + let Path(rating_id) = parts + .extract::>() + .await + .map_err(|_| ChaosError::BadRequest)?; + + assert_user_is_rating_creator_and_organisation_member(user_id, rating_id, pool).await?; + + Ok(RatingCreator { user_id }) + } +} diff --git a/backend/server/src/models/mod.rs b/backend/server/src/models/mod.rs index bb79ea9d0..1bc24e059 100644 --- a/backend/server/src/models/mod.rs +++ b/backend/server/src/models/mod.rs @@ -5,6 +5,7 @@ pub mod campaign; pub mod error; pub mod question; pub mod organisation; +pub mod ratings; pub mod role; pub mod storage; pub mod transaction; diff --git a/backend/server/src/models/question.rs b/backend/server/src/models/question.rs index 307a7aae7..27eb5e854 100644 --- a/backend/server/src/models/question.rs +++ b/backend/server/src/models/question.rs @@ -1,5 +1,4 @@ use crate::models::error::ChaosError; -use anyhow::{bail, Result}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use sqlx::{Pool, Postgres, QueryBuilder, Row}; @@ -87,7 +86,7 @@ pub struct MultiOptionQuestionOption { } impl QuestionData { - pub async fn validate(self) -> Result<()> { + pub async fn validate(self) -> Result<(), ChaosError> { match self { Self::ShortAnswer => Ok(()), Self::MultiChoice(data) @@ -98,12 +97,12 @@ impl QuestionData { return Ok(()); }; - bail!("Invalid number of options.") + Err(ChaosError::BadRequest) } } } - pub async fn insert_into_db(self, question_id: i64, pool: &Pool, mut snowflake_generator: SnowflakeIdGenerator) -> Result<()> { + pub async fn insert_into_db(self, question_id: i64, pool: &Pool, mut snowflake_generator: SnowflakeIdGenerator) -> Result<(), ChaosError> { match self { Self::ShortAnswer => Ok(()), Self::MultiChoice(data) diff --git a/backend/server/src/models/ratings.rs b/backend/server/src/models/ratings.rs new file mode 100644 index 000000000..de01838fa --- /dev/null +++ b/backend/server/src/models/ratings.rs @@ -0,0 +1,157 @@ +use crate::models::error::ChaosError; +use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; +use snowflake::SnowflakeIdGenerator; +use sqlx::{FromRow, Postgres, Transaction}; +use std::ops::DerefMut; + +#[derive(Deserialize, Serialize, Clone, FromRow, Debug)] +pub struct Rating { + pub id: i64, + pub application_id: i64, + pub rater_user_id: i64, + pub rating: i32, + pub comment: Option, + pub created_at: DateTime, + pub updated_at: DateTime, +} + +#[derive(Deserialize, Serialize)] +pub struct NewRating { + pub rater_user_id: i64, + pub rating: i32, + pub comment: Option, +} + +#[derive(Deserialize, Serialize)] +pub struct RatingDetails { + pub id: i64, + pub rater_id: i64, + pub rater_name: String, + pub rating: i32, + pub comment: Option, + pub updated_at: DateTime, +} + +#[derive(Deserialize, Serialize)] +pub struct ApplicationRatings { + pub ratings: Vec, +} + +impl Rating { + /// Create a new rating. + pub async fn create( + new_rating: NewRating, + application_id: i64, + mut snowflake_generator: SnowflakeIdGenerator, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result<(), ChaosError> { + let rating_id = snowflake_generator.generate(); + let rater_user_id = new_rating.rater_user_id; + let rating = new_rating.rating; + let comment = new_rating.comment; + + sqlx::query!( + " + INSERT INTO application_ratings (id, application_id, rater_id, rating, comment) + VALUES ($1, $2, $3, $4, $5) + ", + rating_id, + application_id, + rater_user_id, + rating, + comment + ) + .execute(transaction.deref_mut()) + .await?; + + Ok(()) + } + + /// Create a new rating. + pub async fn update( + rating_id: i64, + updated_rating: NewRating, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result<(), ChaosError> { + let rating = updated_rating.rating; + let comment = updated_rating.comment; + let current_time = Utc::now(); + + let _ = sqlx::query!( + " + UPDATE application_ratings + SET rating = $2, comment = $3, updated_at = $4 + WHERE id = $1 + RETURNING id; + ", + rating_id, + rating, + comment, + current_time + ) + .fetch_one(transaction.deref_mut()) + .await?; + + Ok(()) + } + + pub async fn get_rating( + rating_id: i64, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result { + let rating = sqlx::query_as!( + RatingDetails, + " + SELECT r.id, rater_id, u.name as rater_name, r.rating, r.comment, r.updated_at + FROM application_ratings r + JOIN users u ON u.id = r.id + WHERE r.id = $1 + ", + rating_id + ) + .fetch_one(transaction.deref_mut()) + .await?; + + Ok(rating) + } + + /// Get all ratings for a certain application. + pub async fn get_all_ratings_from_application_id( + application_id: i64, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result { + let ratings = sqlx::query_as!( + RatingDetails, + " + SELECT r.id, rater_id, u.name as rater_name, r.rating, r.comment, r.updated_at + FROM application_ratings r + JOIN users u ON u.id = r.id + WHERE r.application_id = $1 + ", + application_id + ) + .fetch_all(transaction.deref_mut()) + .await?; + + Ok(ApplicationRatings { ratings }) + } + + pub async fn delete( + rating_id: i64, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result<(), ChaosError> { + // Throws error if rating id doesn't exist. + let _ = sqlx::query!( + " + DELETE FROM application_ratings WHERE id = $1 + RETURNING id; + ", + rating_id + ) + .fetch_one(transaction.deref_mut()) + .await?; + + Ok(()) + } +} diff --git a/backend/server/src/service/mod.rs b/backend/server/src/service/mod.rs index 21940ccd7..2e0836227 100644 --- a/backend/server/src/service/mod.rs +++ b/backend/server/src/service/mod.rs @@ -3,5 +3,6 @@ pub mod campaign; pub mod jwt; pub mod oauth2; pub mod organisation; +pub mod ratings; pub mod role; pub mod application; diff --git a/backend/server/src/service/organisation.rs b/backend/server/src/service/organisation.rs index 31396cdcc..cf7f0e5e0 100644 --- a/backend/server/src/service/organisation.rs +++ b/backend/server/src/service/organisation.rs @@ -1,7 +1,7 @@ use crate::models::error::ChaosError; use sqlx::{Pool, Postgres}; -pub async fn user_is_organisation_admin( +pub async fn assert_user_is_organisation_admin( user_id: i64, organisation_id: i64, pool: &Pool, diff --git a/backend/server/src/service/ratings.rs b/backend/server/src/service/ratings.rs new file mode 100644 index 000000000..0ff6b0951 --- /dev/null +++ b/backend/server/src/service/ratings.rs @@ -0,0 +1,125 @@ +use crate::models::campaign::Campaign; +use crate::models::error::ChaosError; +use crate::models::organisation::{Member, MemberList, OrganisationDetails, OrganisationRole}; +use chrono::{DateTime, Utc}; +use snowflake::SnowflakeIdGenerator; +use sqlx::{Pool, Postgres, Transaction}; +use std::ops::DerefMut; +use uuid::Uuid; + +/// Any member of the organisation that owns the campaign is an application +/// viewer, because all members are either directors or execs (TODO: might be +/// changed in the future). +pub async fn assert_user_is_application_reviewer_given_rating_id( + user_id: i64, + rating_id: i64, + pool: &Pool, +) -> Result<(), ChaosError> { + let is_admin = sqlx::query!( + r#" + SELECT EXISTS ( + SELECT 1 + FROM organisation_members om + JOIN campaigns c ON om.organisation_id = c.organisation_id + JOIN applications a ON a.campaign_id = c.id + JOIN application_ratings ar ON ar.application_id = a.id + -- Find the organisation that this application rating belongs to + -- (via the campaign the rating belongs to). + WHERE ar.id = $1 + -- Assert user is member of the organisation that owns the campaign + -- this application belongs to. + AND om.user_id = $2 + ) + "#, + rating_id, + user_id + ) + .fetch_one(pool) + .await? + .exists + .expect("`exists` should always exist in this query result"); + + if !is_admin { + return Err(ChaosError::Unauthorized); + } + + Ok(()) +} + +/// Assert the given user is the creator of the rating with the given id and +/// also a current member of the organisation the rating/application is +/// associated with. +pub async fn assert_user_is_rating_creator_and_organisation_member( + user_id: i64, + rating_id: i64, + pool: &Pool, +) -> Result<(), ChaosError> { + let is_admin = sqlx::query!( + r#" + SELECT EXISTS ( + SELECT 1 + FROM organisation_members om + JOIN campaigns c ON om.organisation_id = c.organisation_id + JOIN applications a ON a.campaign_id = c.id + JOIN application_ratings ar ON ar.application_id = a.id + -- Find the organisation that this application rating belongs to + -- (via the campaign the rating belongs to). + WHERE ar.id = $1 + -- Assert user is the rater of the application rating. + AND ar.rater_id = $2 + -- Assert user is current member of the organisation that owns the + -- campaign this application belongs to. + AND om.user_id = $2 + ) + "#, + rating_id, + user_id + ) + .fetch_one(pool) + .await? + .exists + .expect("`exists` should always exist in this query result"); + + if !is_admin { + return Err(ChaosError::Unauthorized); + } + + Ok(()) +} + +/// Assert the given user a current member of the organisation the application is +/// associated with. +pub async fn assert_user_is_organisation_member( + user_id: i64, + application_id: i64, + pool: &Pool, +) -> Result<(), ChaosError> { + let is_admin = sqlx::query!( + r#" + SELECT EXISTS ( + SELECT 1 + FROM organisation_members om + JOIN campaigns c ON om.organisation_id = c.organisation_id + JOIN applications a ON a.campaign_id = c.id + -- Find the organisation that this application rating belongs to + -- (via the campaign the rating belongs to). + WHERE a.id = $1 + -- Assert user is current member of the organisation that owns the + -- campaign this application belongs to. + AND om.user_id = $2 + ) + "#, + application_id, + user_id + ) + .fetch_one(pool) + .await? + .exists + .expect("`exists` should always exist in this query result"); + + if !is_admin { + return Err(ChaosError::Unauthorized); + } + + Ok(()) +} From 361d92a31816585ba3534139979bd17a84307929 Mon Sep 17 00:00:00 2001 From: Kavika Date: Sat, 23 Nov 2024 14:21:34 +1100 Subject: [PATCH 35/56] Question & Answer CRUD (#526) * initially defer foreign key updates on questions and options * add multi_choice_options unique constraint to (question_id, display_order) * fix warnings * `Question` model implementation * rename "ratings" to "rating" * rename `RatingHandler::create_rating()` * remove whitespace on indexes in migrations * add roles support for questions * Question CRUD * fix `id` to `role_id` in filtering by campaign and role * fix forgotten transaction commits * Answer CRUD * ran cargo format * use `fetch_one()` to check valid id * fix path not stating with `/` * add `cargo run` to CI/CD for rust * remove `cargo run` from rust pipeline * remove todo clarifying authZ Co-authored-by: Alex Miao <79033892+AlexMIaoPU@users.noreply.github.com> * fix rater_id passed in json * commit Organisation member transactions * move `Router` creation to `models/app.rs` * change `QuestionType` `if`/`else` to `match` statement --------- Co-authored-by: Alex Miao <79033892+AlexMIaoPU@users.noreply.github.com> --- .github/workflows/rust.yml | 6 +- .../20240406023149_create_users.sql | 2 +- .../20240406024211_create_organisations.sql | 2 +- .../20240406025537_create_campaigns.sql | 2 +- .../20240406031400_create_questions.sql | 28 +- .../20240406031915_create_applications.sql | 15 +- backend/server/src/handler/answer.rs | 87 +++ backend/server/src/handler/application.rs | 4 +- backend/server/src/handler/campaign.rs | 9 +- backend/server/src/handler/mod.rs | 8 +- backend/server/src/handler/organisation.rs | 10 +- backend/server/src/handler/question.rs | 102 ++++ .../src/handler/{ratings.rs => rating.rs} | 14 +- backend/server/src/handler/role.rs | 2 +- backend/server/src/handler/user.rs | 18 +- backend/server/src/main.rs | 161 +----- backend/server/src/models/answer.rs | 438 ++++++++++++++- backend/server/src/models/app.rs | 201 ++++++- backend/server/src/models/application.rs | 126 +++-- backend/server/src/models/auth.rs | 138 ++++- backend/server/src/models/campaign.rs | 18 +- backend/server/src/models/error.rs | 3 + backend/server/src/models/mod.rs | 7 +- backend/server/src/models/organisation.rs | 48 +- backend/server/src/models/question.rs | 508 +++++++++++++++++- .../src/models/{ratings.rs => rating.rs} | 9 +- backend/server/src/models/role.rs | 12 +- backend/server/src/models/user.rs | 70 ++- backend/server/src/service/answer.rs | 32 ++ backend/server/src/service/application.rs | 30 +- backend/server/src/service/mod.rs | 6 +- backend/server/src/service/question.rs | 32 ++ .../src/service/{ratings.rs => rating.rs} | 8 +- 33 files changed, 1793 insertions(+), 363 deletions(-) create mode 100644 backend/server/src/handler/answer.rs create mode 100644 backend/server/src/handler/question.rs rename backend/server/src/handler/{ratings.rs => rating.rs} (88%) rename backend/server/src/models/{ratings.rs => rating.rs} (96%) create mode 100644 backend/server/src/service/answer.rs create mode 100644 backend/server/src/service/question.rs rename backend/server/src/service/{ratings.rs => rating.rs} (93%) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 8788bb704..c2916e284 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -30,7 +30,11 @@ jobs: echo "GOOGLE_CLIENT_ID=test" >> backend/.env echo "GOOGLE_CLIENT_SECRET=test" >> backend/.env echo "GOOGLE_REDIRECT_URI=http://localhost:3000/auth/callback" >> backend/.env - echo "ROCKET_DATABASES='{}'" >> backend/.env + echo "S3_BUCKET_NAME=chaos-storage" >> backend/.env + echo "S3_ACCESS_KEY=test_access_key" >> backend/.env + echo "S3_SECRET_KEY=test_secret_key" >> backend/.env + echo "S3_ENDPOINT=https://chaos-storage.s3.ap-southeast-1.amazonaws.com" >> backend/.env + echo "S3_REGION_NAME=ap-southeast-1" >> backend/.env # selecting a toolchain either by action or manual `rustup` calls should happen # before the plugin, as it uses the current rustc version as its cache key - uses: actions-rs/toolchain@v1 diff --git a/backend/migrations/20240406023149_create_users.sql b/backend/migrations/20240406023149_create_users.sql index b820e2d2b..94fa0440d 100644 --- a/backend/migrations/20240406023149_create_users.sql +++ b/backend/migrations/20240406023149_create_users.sql @@ -14,4 +14,4 @@ CREATE TABLE users ( updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP ); -CREATE UNIQUE INDEX IDX_users_email_lower on users ((lower(email))); \ No newline at end of file +CREATE UNIQUE INDEX IDX_users_email_lower on users((lower(email))); \ No newline at end of file diff --git a/backend/migrations/20240406024211_create_organisations.sql b/backend/migrations/20240406024211_create_organisations.sql index 008777c16..ec67f1903 100644 --- a/backend/migrations/20240406024211_create_organisations.sql +++ b/backend/migrations/20240406024211_create_organisations.sql @@ -21,4 +21,4 @@ CREATE TABLE organisation_members ( ); -CREATE INDEX IDX_organisation_admins_organisation on organisation_members (organisation_id); +CREATE INDEX IDX_organisation_admins_organisation on organisation_members(organisation_id); diff --git a/backend/migrations/20240406025537_create_campaigns.sql b/backend/migrations/20240406025537_create_campaigns.sql index 757a3e630..c300ee80f 100644 --- a/backend/migrations/20240406025537_create_campaigns.sql +++ b/backend/migrations/20240406025537_create_campaigns.sql @@ -32,4 +32,4 @@ CREATE TABLE campaign_roles ( ON UPDATE CASCADE ); -CREATE INDEX IDX_campaign_roles_campaign on campaign_roles (campaign_id); \ No newline at end of file +CREATE INDEX IDX_campaign_roles_campaign on campaign_roles(campaign_id); \ No newline at end of file diff --git a/backend/migrations/20240406031400_create_questions.sql b/backend/migrations/20240406031400_create_questions.sql index 24f01d971..ec44dea0e 100644 --- a/backend/migrations/20240406031400_create_questions.sql +++ b/backend/migrations/20240406031400_create_questions.sql @@ -5,7 +5,7 @@ CREATE TABLE questions ( title TEXT NOT NULL, description TEXT, common BOOLEAN NOT NULL, - required BOOLEAN, + required BOOLEAN NOT NULL, question_type question_type NOT NULL, campaign_id BIGINT NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, @@ -27,6 +27,30 @@ CREATE TABLE multi_option_question_options ( REFERENCES questions(id) ON DELETE CASCADE ON UPDATE CASCADE + DEFERRABLE INITIALLY DEFERRED, + UNIQUE (question_id, display_order) ); -CREATE INDEX IDX_multi_option_question_options_questions on multi_option_question_options (question_id); \ No newline at end of file +CREATE INDEX IDX_multi_option_question_options_questions on multi_option_question_options(question_id); + +CREATE TABLE question_roles ( + id BIGSERIAL PRIMARY KEY, + question_id BIGINT NOT NULL, + role_id BIGINT NOT NULL, + CONSTRAINT FK_question_roles_questions + FOREIGN KEY(question_id) + REFERENCES questions(id) + ON DELETE CASCADE + ON UPDATE CASCADE + DEFERRABLE INITIALLY DEFERRED, + CONSTRAINT FK_question_roles_roles + FOREIGN KEY(role_id) + REFERENCES campaign_roles(id) + ON DELETE CASCADE + ON UPDATE CASCADE + DEFERRABLE INITIALLY DEFERRED, + UNIQUE (question_id, role_id) +); + +CREATE INDEX IDX_question_roles_questions on question_roles(question_id); +CREATE INDEX IDX_question_roles_roles on question_roles(role_id); \ No newline at end of file diff --git a/backend/migrations/20240406031915_create_applications.sql b/backend/migrations/20240406031915_create_applications.sql index 1adf0d9cf..01ee6439c 100644 --- a/backend/migrations/20240406031915_create_applications.sql +++ b/backend/migrations/20240406031915_create_applications.sql @@ -53,6 +53,7 @@ CREATE TABLE answers ( REFERENCES questions(id) ON DELETE CASCADE ON UPDATE CASCADE + DEFERRABLE INITIALLY DEFERRED ); CREATE INDEX IDX_answers_applications on answers (application_id); @@ -79,7 +80,8 @@ CREATE TABLE multi_option_answer_options ( FOREIGN KEY(option_id) REFERENCES multi_option_question_options(id) ON DELETE CASCADE - ON UPDATE CASCADE, + ON UPDATE CASCADE + DEFERRABLE INITIALLY DEFERRED, CONSTRAINT FK_multi_option_answer_options_answers FOREIGN KEY(answer_id) REFERENCES answers(id) @@ -96,7 +98,8 @@ CREATE TABLE ranking_answer_rankings ( FOREIGN KEY(option_id) REFERENCES multi_option_question_options(id) ON DELETE CASCADE - ON UPDATE CASCADE, + ON UPDATE CASCADE + DEFERRABLE INITIALLY DEFERRED, CONSTRAINT FK_ranking_answer_rankings_answers FOREIGN KEY(answer_id) REFERENCES answers(id) @@ -104,8 +107,8 @@ CREATE TABLE ranking_answer_rankings ( ON UPDATE CASCADE ); -CREATE INDEX IDX_multi_option_answer_options_question_options on multi_option_answer_options (option_id); -CREATE INDEX IDX_multi_option_answer_options_answers on multi_option_answer_options (answer_id); +CREATE INDEX IDX_multi_option_answer_options_question_options on multi_option_answer_options(option_id); +CREATE INDEX IDX_multi_option_answer_options_answers on multi_option_answer_options(answer_id); CREATE TABLE application_ratings ( id BIGINT PRIMARY KEY, @@ -127,5 +130,5 @@ CREATE TABLE application_ratings ( ON UPDATE CASCADE ); -CREATE INDEX IDX_application_ratings_applications on application_ratings (application_id); -CREATE INDEX IDX_application_ratings_users on application_ratings (rater_id); \ No newline at end of file +CREATE INDEX IDX_application_ratings_applications on application_ratings(application_id); +CREATE INDEX IDX_application_ratings_users on application_ratings(rater_id); \ No newline at end of file diff --git a/backend/server/src/handler/answer.rs b/backend/server/src/handler/answer.rs new file mode 100644 index 000000000..34f3e0ea6 --- /dev/null +++ b/backend/server/src/handler/answer.rs @@ -0,0 +1,87 @@ +use crate::models::answer::{Answer, NewAnswer}; +use crate::models::app::AppState; +use crate::models::auth::{AnswerOwner, ApplicationOwner, AuthUser}; +use crate::models::error::ChaosError; +use crate::models::transaction::DBTransaction; +use axum::extract::{Json, Path, State}; +use axum::http::StatusCode; +use axum::response::IntoResponse; +use serde_json::json; + +pub struct AnswerHandler; + +impl AnswerHandler { + pub async fn create( + State(state): State, + Path(path): Path, + user: AuthUser, + mut transaction: DBTransaction<'_>, + Json(data): Json, + ) -> Result { + let id = Answer::create( + user.user_id, + data.application_id, + data.question_id, + data.answer_data, + state.snowflake_generator, + &mut transaction.tx, + ) + .await?; + + transaction.tx.commit().await?; + + Ok((StatusCode::OK, Json(json!({"id": id})))) + } + + pub async fn get_all_common_by_application( + Path(application_id): Path, + _owner: ApplicationOwner, + mut transaction: DBTransaction<'_>, + ) -> Result { + let answers = + Answer::get_all_common_by_application(application_id, &mut transaction.tx).await?; + + transaction.tx.commit().await?; + + Ok((StatusCode::OK, Json(answers))) + } + + pub async fn get_all_by_application_and_role( + Path((application_id, role_id)): Path<(i64, i64)>, + _owner: ApplicationOwner, + mut transaction: DBTransaction<'_>, + ) -> Result { + let answers = + Answer::get_all_by_application_and_role(application_id, role_id, &mut transaction.tx) + .await?; + + transaction.tx.commit().await?; + + Ok((StatusCode::OK, Json(answers))) + } + + pub async fn update( + Path(answer_id): Path, + _owner: AnswerOwner, + mut transaction: DBTransaction<'_>, + Json(data): Json, + ) -> Result { + Answer::update(answer_id, data.answer_data, &mut transaction.tx).await?; + + transaction.tx.commit().await?; + + Ok((StatusCode::OK, "Successfully updated answer")) + } + + pub async fn delete( + Path(answer_id): Path, + _owner: AnswerOwner, + mut transaction: DBTransaction<'_>, + ) -> Result { + Answer::delete(answer_id, &mut transaction.tx).await?; + + transaction.tx.commit().await?; + + Ok((StatusCode::OK, "Successfully deleted answer")) + } +} diff --git a/backend/server/src/handler/application.rs b/backend/server/src/handler/application.rs index 15d75e413..8f6c2ecf3 100644 --- a/backend/server/src/handler/application.rs +++ b/backend/server/src/handler/application.rs @@ -1,6 +1,6 @@ use crate::models::app::AppState; use crate::models::application::{Application, ApplicationStatus}; -use crate::models::auth::{AuthUser, ApplicationAdmin}; +use crate::models::auth::{ApplicationAdmin, AuthUser}; use crate::models::error::ChaosError; use crate::models::transaction::DBTransaction; use axum::extract::{Json, Path, State}; @@ -48,4 +48,4 @@ impl ApplicationHandler { transaction.tx.commit().await?; Ok((StatusCode::OK, Json(applications))) } -} \ No newline at end of file +} diff --git a/backend/server/src/handler/campaign.rs b/backend/server/src/handler/campaign.rs index f5a827d36..ed5b9e249 100644 --- a/backend/server/src/handler/campaign.rs +++ b/backend/server/src/handler/campaign.rs @@ -86,7 +86,14 @@ impl CampaignHandler { mut transaction: DBTransaction<'_>, Json(data): Json, ) -> Result { - Application::create(id, user.user_id, data, state.snowflake_generator, &mut transaction.tx).await?; + Application::create( + id, + user.user_id, + data, + state.snowflake_generator, + &mut transaction.tx, + ) + .await?; transaction.tx.commit().await?; Ok((StatusCode::OK, "Successfully created application")) } diff --git a/backend/server/src/handler/mod.rs b/backend/server/src/handler/mod.rs index c577af3ec..73a946273 100644 --- a/backend/server/src/handler/mod.rs +++ b/backend/server/src/handler/mod.rs @@ -1,7 +1,9 @@ +pub mod answer; +pub mod application; pub mod auth; -pub mod user; pub mod campaign; pub mod organisation; -pub mod ratings; +pub mod question; +pub mod rating; pub mod role; -pub mod application; +pub mod user; diff --git a/backend/server/src/handler/organisation.rs b/backend/server/src/handler/organisation.rs index 78ec8bc6e..f98b27b23 100644 --- a/backend/server/src/handler/organisation.rs +++ b/backend/server/src/handler/organisation.rs @@ -91,13 +91,14 @@ impl OrganisationHandler { } pub async fn remove_admin( - State(state): State, + mut transaction: DBTransaction<'_>, Path(id): Path, _super_user: SuperUser, Json(request_body): Json, ) -> Result { - Organisation::remove_admin(id, request_body.user_id, &state.db).await?; + Organisation::remove_admin(id, request_body.user_id, &mut transaction.tx).await?; + transaction.tx.commit().await?; Ok(( StatusCode::OK, "Successfully removed member from organisation", @@ -105,13 +106,14 @@ impl OrganisationHandler { } pub async fn remove_member( - State(state): State, + mut transaction: DBTransaction<'_>, Path(id): Path, _admin: OrganisationAdmin, Json(request_body): Json, ) -> Result { - Organisation::remove_member(id, request_body.user_id, &state.db).await?; + Organisation::remove_member(id, request_body.user_id, &mut transaction.tx).await?; + transaction.tx.commit().await?; Ok(( StatusCode::OK, "Successfully removed member from organisation", diff --git a/backend/server/src/handler/question.rs b/backend/server/src/handler/question.rs new file mode 100644 index 000000000..c425c96bc --- /dev/null +++ b/backend/server/src/handler/question.rs @@ -0,0 +1,102 @@ +use crate::models::app::AppState; +use crate::models::auth::{AuthUser, CampaignAdmin, QuestionAdmin}; +use crate::models::error::ChaosError; +use crate::models::question::{NewQuestion, Question}; +use crate::models::transaction::DBTransaction; +use axum::extract::{Json, Path, State}; +use axum::http::StatusCode; +use axum::response::IntoResponse; +use serde_json::json; + +pub struct QuestionHandler; + +impl QuestionHandler { + pub async fn create( + State(state): State, + Path(campaign_id): Path, + _admin: CampaignAdmin, + mut transaction: DBTransaction<'_>, + Json(data): Json, + ) -> Result { + let id = Question::create( + campaign_id, + data.title, + data.description, + data.common, + data.roles, + data.required, + data.question_data, + state.snowflake_generator, + &mut transaction.tx, + ) + .await?; + + transaction.tx.commit().await?; + + Ok((StatusCode::OK, Json(json!({"id": id})))) + } + + pub async fn get_all_by_campaign_and_role( + Path((campaign_id, role_id)): Path<(i64, i64)>, + _user: AuthUser, + mut transaction: DBTransaction<'_>, + ) -> Result { + let questions = + Question::get_all_by_campaign_and_role(campaign_id, role_id, &mut transaction.tx) + .await?; + + transaction.tx.commit().await?; + + Ok((StatusCode::OK, Json(questions))) + } + + pub async fn get_all_common_by_campaign( + Path(campaign_id): Path, + _user: AuthUser, + mut transaction: DBTransaction<'_>, + ) -> Result { + let questions = + Question::get_all_common_by_campaign(campaign_id, &mut transaction.tx).await?; + + transaction.tx.commit().await?; + + Ok((StatusCode::OK, Json(questions))) + } + + pub async fn update( + State(state): State, + Path(question_id): Path, + _admin: QuestionAdmin, + mut transaction: DBTransaction<'_>, + Json(data): Json, + ) -> Result { + Question::update( + question_id, + data.title, + data.description, + data.common, + data.roles, + data.required, + data.question_data, + &mut transaction.tx, + state.snowflake_generator, + ) + .await?; + + transaction.tx.commit().await?; + + Ok((StatusCode::OK, "Successfully updated question")) + } + + pub async fn delete( + Path(question_id): Path, + _admin: QuestionAdmin, + mut transaction: DBTransaction<'_>, + ) -> Result { + Question::delete(question_id, &mut transaction.tx).await?; + + transaction.tx.commit().await?; + + Ok((StatusCode::OK, "Successfully deleted question")) + } +} diff --git a/backend/server/src/handler/ratings.rs b/backend/server/src/handler/rating.rs similarity index 88% rename from backend/server/src/handler/ratings.rs rename to backend/server/src/handler/rating.rs index d8d6071f0..2ec36960a 100644 --- a/backend/server/src/handler/ratings.rs +++ b/backend/server/src/handler/rating.rs @@ -1,29 +1,29 @@ use crate::models::app::AppState; use crate::models::auth::{ ApplicationCreatorGivenApplicationId, ApplicationReviewerGivenApplicationId, - ApplicationReviewerGivenRatingId, RatingCreator, SuperUser, + ApplicationReviewerGivenRatingId, RatingCreator, }; use crate::models::error::ChaosError; -use crate::models::ratings::{NewRating, Rating}; +use crate::models::rating::{NewRating, Rating}; use crate::models::transaction::DBTransaction; use axum::extract::{Json, Path, State}; use axum::http::StatusCode; use axum::response::IntoResponse; -pub struct RatingsHandler; +pub struct RatingHandler; -impl RatingsHandler { - // TODO: are all the user permissions as required? Who should be able to do what with ratings? - pub async fn create_rating( +impl RatingHandler { + pub async fn create( State(state): State, Path(application_id): Path, - _admin: ApplicationCreatorGivenApplicationId, + admin: ApplicationReviewerGivenApplicationId, mut transaction: DBTransaction<'_>, Json(new_rating): Json, ) -> Result { Rating::create( new_rating, application_id, + admin.user_id, state.snowflake_generator, &mut transaction.tx, ) diff --git a/backend/server/src/handler/role.rs b/backend/server/src/handler/role.rs index c1e9d2daf..5bcb2b1fa 100644 --- a/backend/server/src/handler/role.rs +++ b/backend/server/src/handler/role.rs @@ -3,8 +3,8 @@ use crate::models::application::Application; use crate::models::auth::{AuthUser, RoleAdmin}; use crate::models::error::ChaosError; use crate::models::role::{Role, RoleUpdate}; -use axum::extract::{Json, Path, State}; use crate::models::transaction::DBTransaction; +use axum::extract::{Json, Path, State}; use axum::http::StatusCode; use axum::response::IntoResponse; diff --git a/backend/server/src/handler/user.rs b/backend/server/src/handler/user.rs index 4909ba910..be5445e1d 100644 --- a/backend/server/src/handler/user.rs +++ b/backend/server/src/handler/user.rs @@ -1,10 +1,10 @@ use crate::models::app::AppState; use crate::models::auth::AuthUser; use crate::models::error::ChaosError; +use crate::models::user::{User, UserDegree, UserGender, UserName, UserPronouns, UserZid}; use axum::extract::{Json, State}; use axum::http::StatusCode; use axum::response::IntoResponse; -use crate::models::user::{User, UserDegree, UserGender, UserName, UserPronouns, UserZid}; pub struct UserHandler; @@ -16,14 +16,14 @@ impl UserHandler { let user = User::get(user.user_id, &state.db).await?; Ok((StatusCode::OK, Json(user))) } - + pub async fn update_name( State(state): State, user: AuthUser, Json(request_body): Json, ) -> Result { User::update_name(user.user_id, request_body.name, &state.db).await?; - + Ok((StatusCode::OK, "Updated username")) } @@ -46,17 +46,17 @@ impl UserHandler { Ok((StatusCode::OK, "Updated gender")) } - + pub async fn update_zid( State(state): State, user: AuthUser, Json(request_body): Json, ) -> Result { User::update_zid(user.user_id, request_body.zid, &state.db).await?; - + Ok((StatusCode::OK, "Updated zid")) } - + pub async fn update_degree( State(state): State, user: AuthUser, @@ -66,12 +66,10 @@ impl UserHandler { user.user_id, request_body.degree_name, request_body.degree_starting_year, - &state.db + &state.db, ) .await?; - + Ok((StatusCode::OK, "Updated user degree")) } } - - diff --git a/backend/server/src/main.rs b/backend/server/src/main.rs index 1acdfa515..a464dd2af 100644 --- a/backend/server/src/main.rs +++ b/backend/server/src/main.rs @@ -1,168 +1,15 @@ -use crate::handler::auth::google_callback; -use handler::user::UserHandler; -use crate::handler::campaign::CampaignHandler; -use crate::handler::organisation::OrganisationHandler; -use crate::handler::application::ApplicationHandler; -use crate::models::storage::Storage; -use anyhow::Result; -use axum::routing::{get, patch, post}; -use axum::Router; -use handler::ratings::RatingsHandler; -use handler::role::RoleHandler; -use jsonwebtoken::{Algorithm, DecodingKey, EncodingKey, Header, Validation}; -use models::app::AppState; -use snowflake::SnowflakeIdGenerator; -use sqlx::postgres::PgPoolOptions; -use std::env; +use crate::models::app::app; +use crate::models::error::ChaosError; mod handler; mod models; mod service; #[tokio::main] -async fn main() -> Result<()> { +async fn main() -> Result<(), ChaosError> { dotenvy::dotenv()?; - // Initialise DB connection - let db_url = env::var("DATABASE_URL") - .expect("Error getting DATABASE_URL") - .to_string(); - let pool = PgPoolOptions::new() - .max_connections(5) - .connect(db_url.as_str()) - .await - .expect("Cannot connect to database"); - - // Initialise JWT settings - let jwt_secret = env::var("JWT_SECRET") - .expect("Error getting JWT_SECRET") - .to_string(); - // let jwt_secret = "I want to cry"; - let encoding_key = EncodingKey::from_secret(jwt_secret.as_bytes()); - let decoding_key = DecodingKey::from_secret(jwt_secret.as_bytes()); - let jwt_header = Header::new(Algorithm::HS512); - let mut jwt_validator = Validation::new(Algorithm::HS512); - jwt_validator.set_issuer(&["Chaos"]); - jwt_validator.set_audience(&["chaos.devsoc.app"]); - - // Initialise reqwest client - let ctx = reqwest::Client::new(); - - // Initialise Snowflake Generator - let snowflake_generator = SnowflakeIdGenerator::new(1, 1); - - // Initialise S3 bucket - let storage_bucket = Storage::init_bucket(); - - // Add all data to AppState - let state = AppState { - db: pool, - ctx, - encoding_key, - decoding_key, - jwt_header, - jwt_validator, - snowflake_generator, - storage_bucket, - }; - - let app = Router::new() - .route("/", get(|| async { "Hello, World!" })) - .route("/api/auth/callback/google", get(google_callback)) - .route("/api/v1/user", get(UserHandler::get)) - .route("/api/v1/user/name", patch(UserHandler::update_name)) - .route("/api/v1/user/pronouns", patch(UserHandler::update_pronouns)) - .route("/api/v1/user/gender", patch(UserHandler::update_gender)) - .route("/api/v1/user/zid", patch(UserHandler::update_zid)) - .route("/api/v1/user/degree", patch(UserHandler::update_degree)) - .route( - "/api/v1/user/applications", - get(ApplicationHandler::get_from_curr_user), - ) - .route("/api/v1/organisation", post(OrganisationHandler::create)) - .route( - "/api/v1/organisation/:organisation_id", - get(OrganisationHandler::get).delete(OrganisationHandler::delete), - ) - .route( - "/api/v1/organisation/:organisation_id/campaign", - post(OrganisationHandler::create_campaign), - ) - .route( - "/api/v1/organisation/:organisation_id/campaigns", - get(OrganisationHandler::get_campaigns), - ) - .route( - "/api/v1/organisation/:organisation_id/logo", - patch(OrganisationHandler::update_logo), - ) - .route( - "/api/v1/organisation/:organisation_id/member", - get(OrganisationHandler::get_members) - .put(OrganisationHandler::update_members) - .delete(OrganisationHandler::remove_member), - ) - .route( - "/api/v1/organisation/:organisation_id/admin", - get(OrganisationHandler::get_admins) - .put(OrganisationHandler::update_admins) - .delete(OrganisationHandler::remove_admin), - ) - .route( - "/api/v1/ratings/:rating_id", - get(RatingsHandler::get) - .delete(RatingsHandler::delete) - .put(RatingsHandler::update), - ) - .route( - "/api/v1/:application_id/rating", - post(RatingsHandler::create_rating), - ) - .route( - "/api/v1/:application_id/ratings", - get(RatingsHandler::get_ratings_for_application), - ) - .route( - "/api/v1/campaign/:campaign_id/role", - post(CampaignHandler::create_role), - ) - .route( - "/api/v1/campaign/:campaign_id/roles", - get(CampaignHandler::get_roles), - ) - .route( - "/api/v1/campaign/:campaign_id/applications", - get(CampaignHandler::get_applications), - ) - .route( - "/api/v1/role/:role_id", - get(RoleHandler::get) - .put(RoleHandler::update) - .delete(RoleHandler::delete), - ) - .route( - "/api/v1/role/:role_id/applications", - get(RoleHandler::get_applications) - ) - .route( - "/api/v1/campaign/:campaign_id", - get(CampaignHandler::get) - .put(CampaignHandler::update) - .delete(CampaignHandler::delete), - ) - .route("/api/v1/campaign", get(CampaignHandler::get_all)) - .route( - "/api/v1/campaign/:campaign_id/banner", - patch(CampaignHandler::update_banner), - ) - .route("api/v1/campaign/:campaign_id/application", - post(CampaignHandler::create_application) - ) - .route("api/v1/application/:application_id", get(ApplicationHandler::get)) - .route("api/v1/application/:application_id/status", patch(ApplicationHandler::set_status)) - .route("api/v1/application/:application_id/private", patch(ApplicationHandler::set_private_status)) - .with_state(state); - + let app = app().await?; let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); axum::serve(listener, app).await.unwrap(); diff --git a/backend/server/src/models/answer.rs b/backend/server/src/models/answer.rs index b892fc18a..670a7ba81 100644 --- a/backend/server/src/models/answer.rs +++ b/backend/server/src/models/answer.rs @@ -1,7 +1,12 @@ use crate::models::error::ChaosError; +use crate::models::question::{ + MultiOptionData, MultiOptionQuestionOption, QuestionData, QuestionType, QuestionTypeParent, +}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; -use sqlx::{Pool, Postgres, QueryBuilder, Row}; +use snowflake::SnowflakeIdGenerator; +use sqlx::{Pool, Postgres, Transaction}; +use std::ops::DerefMut; /// The `Answer` type that will be sent in API responses. /// @@ -11,7 +16,6 @@ use sqlx::{Pool, Postgres, QueryBuilder, Row}; /// ```json /// { /// "id": 7233828375289773948, -/// "application_id": 7233828375289125398, /// "question_id": 7233828375289139200, /// "answer_type": "MultiChoice", /// "data": 7233828393325384908, @@ -22,7 +26,6 @@ use sqlx::{Pool, Postgres, QueryBuilder, Row}; #[derive(Deserialize, Serialize)] pub struct Answer { id: i64, - application_id: i64, question_id: i64, #[serde(flatten)] @@ -32,66 +35,420 @@ pub struct Answer { updated_at: DateTime, } +#[derive(Deserialize)] +pub struct NewAnswer { + pub application_id: i64, + pub question_id: i64, + + #[serde(flatten)] + pub answer_data: AnswerData, +} + +#[derive(Deserialize, sqlx::FromRow)] +pub struct AnswerRawData { + id: i64, + question_id: i64, + question_type: QuestionType, + short_answer_answer: Option, + multi_option_answers: Option>, + ranking_answers: Option>, + created_at: DateTime, + updated_at: DateTime, +} + +#[derive(Deserialize)] +pub struct AnswerTypeApplicationId { + question_type: QuestionType, + application_id: i64, +} + +impl Answer { + pub async fn create( + user_id: i64, + application_id: i64, + question_id: i64, + answer_data: AnswerData, + mut snowflake_generator: SnowflakeIdGenerator, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result { + answer_data.validate()?; + + let id = snowflake_generator.generate(); + + sqlx::query!( + " + INSERT INTO answers (id, application_id, question_id) + VALUES ($1, $2, $3) + ", + id, + application_id, + question_id + ) + .execute(transaction.deref_mut()) + .await?; + + answer_data.insert_into_db(id, transaction).await?; + + Ok(id) + } + + pub async fn get( + id: i64, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result { + let answer_raw_data: AnswerRawData = sqlx::query_as( + " + SELECT + a.id, + a.question_id, + q.question_type AS \"question_type: QuestionType\", + a.created_at, + a.updated_at, + saa.text AS short_answer_answer, + array_agg( + moao.option_id + ) multi_option_answers, + array_agg( + rar.option_id ORDER BY rar.rank + ) ranking_answers + FROM + answers a + JOIN questions q ON a.question_id = q.id + LEFT JOIN + multi_option_answer_options moao ON moao.answer_id = a.id + AND q.question_type IN ('MultiChoice', 'MultiSelect', 'DropDown') + + LEFT JOIN + short_answer_answers saa ON saa.answer_id = a.id + AND q.question_type = 'ShortAnswer' + + LEFT JOIN + ranking_answer_rankings rar ON rar.answer_id = a.id + AND q.question_type = 'Ranking' + WHERE q.id = $1 + GROUP BY + a.id + ", + ) + .bind(id) + .fetch_one(transaction.deref_mut()) + .await?; + + let answer_data = AnswerData::from_answer_raw_data( + answer_raw_data.question_type, + answer_raw_data.short_answer_answer, + answer_raw_data.multi_option_answers, + answer_raw_data.ranking_answers, + ); + + Ok(Answer { + id, + question_id: answer_raw_data.question_id, + answer_data, + created_at: answer_raw_data.created_at, + updated_at: answer_raw_data.updated_at, + }) + } + + pub async fn get_all_common_by_application( + application_id: i64, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result, ChaosError> { + let answer_raw_data: Vec = sqlx::query_as( + " + SELECT + a.id, + a.question_id, + q.question_type AS \"question_type: QuestionType\", + a.created_at, + a.updated_at, + saa.text AS short_answer_answer, + array_agg( + moao.option_id + ) multi_option_answers, + array_agg( + rar.option_id ORDER BY rar.rank + ) ranking_answers + FROM + answers a + JOIN questions q ON a.question_id = q.id + LEFT JOIN + multi_option_answer_options moao ON moao.answer_id = a.id + AND q.question_type IN ('MultiChoice', 'MultiSelect', 'DropDown') + + LEFT JOIN + short_answer_answers saa ON saa.answer_id = a.id + AND q.question_type = 'ShortAnswer' + + LEFT JOIN + ranking_answer_rankings rar ON rar.answer_id = a.id + AND q.question_type = 'Ranking' + WHERE a.application_id = $1 AND q.common = true + GROUP BY + a.id + ", + ) + .bind(application_id) + .fetch_all(transaction.deref_mut()) + .await?; + + let answers = answer_raw_data + .into_iter() + .map(|answer_raw_data| { + let answer_data = AnswerData::from_answer_raw_data( + answer_raw_data.question_type, + answer_raw_data.short_answer_answer, + answer_raw_data.multi_option_answers, + answer_raw_data.ranking_answers, + ); + + Answer { + id: answer_raw_data.id, + question_id: answer_raw_data.question_id, + answer_data, + created_at: answer_raw_data.created_at, + updated_at: answer_raw_data.updated_at, + } + }) + .collect(); + + Ok(answers) + } + + pub async fn get_all_by_application_and_role( + application_id: i64, + role_id: i64, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result, ChaosError> { + let answer_raw_data: Vec = sqlx::query_as( + " + SELECT + a.id, + a.question_id, + q.question_type AS \"question_type: QuestionType\", + a.created_at, + a.updated_at, + saa.text AS short_answer_answer, + array_agg( + moao.option_id + ) multi_option_answers, + array_agg( + rar.option_id ORDER BY rar.rank + ) ranking_answers + FROM + answers a + JOIN questions q ON a.question_id = q.id + JOIN question_roles qr ON q.id = qr.question_id + LEFT JOIN + multi_option_answer_options moao ON moao.answer_id = a.id + AND q.question_type IN ('MultiChoice', 'MultiSelect', 'DropDown') + + LEFT JOIN + short_answer_answers saa ON saa.answer_id = a.id + AND q.question_type = 'ShortAnswer' + + LEFT JOIN + ranking_answer_rankings rar ON rar.answer_id = a.id + AND q.question_type = 'Ranking' + WHERE a.application_id = $1 AND qr.role_id = $2 AND q.common = true + GROUP BY + a.id + ", + ) + .bind(application_id) + .bind(role_id) + .fetch_all(transaction.deref_mut()) + .await?; + + let answers = answer_raw_data + .into_iter() + .map(|answer_raw_data| { + let answer_data = AnswerData::from_answer_raw_data( + answer_raw_data.question_type, + answer_raw_data.short_answer_answer, + answer_raw_data.multi_option_answers, + answer_raw_data.ranking_answers, + ); + + Answer { + id: answer_raw_data.id, + question_id: answer_raw_data.question_id, + answer_data, + created_at: answer_raw_data.created_at, + updated_at: answer_raw_data.updated_at, + } + }) + .collect(); + + Ok(answers) + } + + pub async fn update( + id: i64, + answer_data: AnswerData, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result<(), ChaosError> { + answer_data.validate()?; + + let answer = sqlx::query_as!( + AnswerTypeApplicationId, + " + SELECT a.application_id, q.question_type AS \"question_type: QuestionType\" + FROM answers a + JOIN questions q ON a.question_id = q.id + WHERE a.id = $1 + ", + id + ) + .fetch_one(transaction.deref_mut()) + .await?; + + let old_data = AnswerData::from_question_type(&answer.question_type); + old_data.delete_from_db(id, transaction).await?; + + answer_data.insert_into_db(id, transaction).await?; + + sqlx::query!( + "UPDATE applications SET updated_at = $1 WHERE id = $2", + Utc::now(), + answer.application_id + ) + .execute(transaction.deref_mut()) + .await?; + + Ok(()) + } + + pub async fn delete( + id: i64, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result<(), ChaosError> { + sqlx::query!("DELETE FROM answers WHERE id = $1 RETURNING id", id) + .fetch_one(transaction.deref_mut()) + .await?; + + Ok(()) + } +} + #[derive(Deserialize, Serialize)] -#[serde( tag = "answer_type", content = "data")] +#[serde(tag = "answer_type", content = "data")] pub enum AnswerData { ShortAnswer(String), MultiChoice(i64), MultiSelect(Vec), DropDown(i64), - Ranking(Vec) + Ranking(Vec), } impl AnswerData { - pub async fn validate(self) -> Result<(), ChaosError> { + fn from_question_type(question_type: &QuestionType) -> Self { + match question_type { + QuestionType::ShortAnswer => AnswerData::ShortAnswer("".to_string()), + QuestionType::MultiChoice => AnswerData::MultiChoice(0), + QuestionType::MultiSelect => AnswerData::MultiSelect(Vec::::new()), + QuestionType::DropDown => AnswerData::DropDown(0), + QuestionType::Ranking => AnswerData::Ranking(Vec::::new()), + } + } + + fn from_answer_raw_data( + question_type: QuestionType, + short_answer_answer: Option, + multi_option_answers: Option>, + ranking_answers: Option>, + ) -> Self { + return match question_type { + QuestionType::ShortAnswer => { + let answer = + short_answer_answer.expect("Data should exist for ShortAnswer variant"); + AnswerData::ShortAnswer(answer) + } + QuestionType::MultiChoice | QuestionType::MultiSelect | QuestionType::DropDown => { + let options = + multi_option_answers.expect("Data should exist for MultiOptionData variants"); + + match question_type { + QuestionType::MultiChoice => AnswerData::MultiChoice(options[0]), + QuestionType::MultiSelect => AnswerData::MultiSelect(options), + QuestionType::DropDown => AnswerData::DropDown(options[0]), + _ => AnswerData::ShortAnswer("".to_string()), // Should never be reached, hence return ShortAnswer + } + } + QuestionType::Ranking => { + let options = ranking_answers.expect("Data should exist for Ranking variant"); + AnswerData::Ranking(options) + } + _ => { + AnswerData::ShortAnswer("".to_string()) // Should never be reached, hence return ShortAnswer + } + }; + } + + pub fn validate(&self) -> Result<(), ChaosError> { match self { - Self::ShortAnswer(text) => if text.len() == 0 { return Err(ChaosError::BadRequest) }, - Self::MultiSelect(data) => if data.len() == 0 { return Err(ChaosError::BadRequest) }, - _ => {}, + Self::ShortAnswer(text) => { + if text.len() == 0 { + return Err(ChaosError::BadRequest); + } + } + Self::MultiSelect(data) | Self::Ranking(data) => { + if data.len() == 0 { + return Err(ChaosError::BadRequest); + } + } + _ => {} } Ok(()) } - pub async fn insert_into_db(self, answer_id: i64, pool: &Pool) -> Result<(), ChaosError> { + pub async fn insert_into_db( + self, + answer_id: i64, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result<(), ChaosError> { match self { Self::ShortAnswer(text) => { - let result = sqlx::query!( + sqlx::query!( "INSERT INTO short_answer_answers (text, answer_id) VALUES ($1, $2)", text, answer_id ) - .execute(pool) + .execute(transaction.deref_mut()) .await?; Ok(()) - }, - Self::MultiChoice(option_id) - | Self::DropDown(option_id) => { - let result = sqlx::query!( + } + Self::MultiChoice(option_id) | Self::DropDown(option_id) => { + sqlx::query!( "INSERT INTO multi_option_answer_options (option_id, answer_id) VALUES ($1, $2)", option_id, answer_id ) - .execute(pool) + .execute(transaction.deref_mut()) .await?; Ok(()) - }, + } Self::MultiSelect(option_ids) => { - let mut query_builder = sqlx::QueryBuilder::new("INSERT INTO multi_option_answer_options (option_id, answer_id)"); + let mut query_builder = sqlx::QueryBuilder::new( + "INSERT INTO multi_option_answer_options (option_id, answer_id)", + ); query_builder.push_values(option_ids, |mut b, option_id| { b.push_bind(option_id).push_bind(answer_id); }); let query = query_builder.build(); - let result = query.execute(pool).await?; + query.execute(transaction.deref_mut()).await?; Ok(()) - }, + } Self::Ranking(option_ids) => { - let mut query_builder = sqlx::QueryBuilder::new("INSERT INTO ranking_answer_rankings (option_id, rank, answer_id)"); + let mut query_builder = sqlx::QueryBuilder::new( + "INSERT INTO ranking_answer_rankings (option_id, rank, answer_id)", + ); let mut rank = 1; query_builder.push_values(option_ids, |mut b, option_id| { @@ -100,10 +457,45 @@ impl AnswerData { }); let query = query_builder.build(); - let result = query.execute(pool).await?; + query.execute(transaction.deref_mut()).await?; Ok(()) } } } + + pub async fn delete_from_db( + self, + answer_id: i64, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result<(), ChaosError> { + match self { + Self::ShortAnswer(_) => { + sqlx::query!( + "DELETE FROM short_answer_answers WHERE answer_id = $1", + answer_id + ) + .execute(transaction.deref_mut()) + .await?; + } + Self::MultiChoice(_) | Self::MultiSelect(_) | Self::DropDown(_) => { + sqlx::query!( + "DELETE FROM multi_option_answer_options WHERE answer_id = $1", + answer_id + ) + .execute(transaction.deref_mut()) + .await?; + } + Self::Ranking(_) => { + sqlx::query!( + "DELETE FROM ranking_answer_rankings WHERE answer_id = $1", + answer_id + ) + .execute(transaction.deref_mut()) + .await?; + } + } + + Ok(()) + } } diff --git a/backend/server/src/models/app.rs b/backend/server/src/models/app.rs index 19ecfbffa..ed41b78fb 100644 --- a/backend/server/src/models/app.rs +++ b/backend/server/src/models/app.rs @@ -1,8 +1,23 @@ -use jsonwebtoken::{DecodingKey, EncodingKey, Header, Validation}; +use crate::handler::answer::AnswerHandler; +use crate::handler::application::ApplicationHandler; +use crate::handler::auth::google_callback; +use crate::handler::campaign::CampaignHandler; +use crate::handler::organisation::OrganisationHandler; +use crate::handler::question::QuestionHandler; +use crate::handler::rating::RatingHandler; +use crate::handler::role::RoleHandler; +use crate::handler::user::UserHandler; +use crate::models::error::ChaosError; +use crate::models::storage::Storage; +use axum::routing::{get, patch, post}; +use axum::Router; +use jsonwebtoken::{Algorithm, DecodingKey, EncodingKey, Header, Validation}; use reqwest::Client as ReqwestClient; use s3::Bucket; use snowflake::SnowflakeIdGenerator; +use sqlx::postgres::PgPoolOptions; use sqlx::{Pool, Postgres}; +use std::env; #[derive(Clone)] pub struct AppState { @@ -15,3 +30,187 @@ pub struct AppState { pub snowflake_generator: SnowflakeIdGenerator, pub storage_bucket: Bucket, } + +pub async fn app() -> Result { + // Initialise DB connection + let db_url = env::var("DATABASE_URL") + .expect("Error getting DATABASE_URL") + .to_string(); + let pool = PgPoolOptions::new() + .max_connections(5) + .connect(db_url.as_str()) + .await + .expect("Cannot connect to database"); + + // Initialise JWT settings + let jwt_secret = env::var("JWT_SECRET") + .expect("Error getting JWT_SECRET") + .to_string(); + // let jwt_secret = "I want to cry"; + let encoding_key = EncodingKey::from_secret(jwt_secret.as_bytes()); + let decoding_key = DecodingKey::from_secret(jwt_secret.as_bytes()); + let jwt_header = Header::new(Algorithm::HS512); + let mut jwt_validator = Validation::new(Algorithm::HS512); + jwt_validator.set_issuer(&["Chaos"]); + jwt_validator.set_audience(&["chaos.devsoc.app"]); + + // Initialise reqwest client + let ctx = reqwest::Client::new(); + + // Initialise Snowflake Generator + let snowflake_generator = SnowflakeIdGenerator::new(1, 1); + + // Initialise S3 bucket + let storage_bucket = Storage::init_bucket(); + + // Add all data to AppState + let state = AppState { + db: pool, + ctx, + encoding_key, + decoding_key, + jwt_header, + jwt_validator, + snowflake_generator, + storage_bucket, + }; + + Ok(Router::new() + .route("/", get(|| async { "Join DevSoc! https://devsoc.app/" })) + .route("/api/auth/callback/google", get(google_callback)) + .route("/api/v1/user", get(UserHandler::get)) + .route("/api/v1/user/name", patch(UserHandler::update_name)) + .route("/api/v1/user/pronouns", patch(UserHandler::update_pronouns)) + .route("/api/v1/user/gender", patch(UserHandler::update_gender)) + .route("/api/v1/user/zid", patch(UserHandler::update_zid)) + .route("/api/v1/user/degree", patch(UserHandler::update_degree)) + .route( + "/api/v1/user/applications", + get(ApplicationHandler::get_from_curr_user), + ) + .route("/api/v1/organisation", post(OrganisationHandler::create)) + .route( + "/api/v1/organisation/:organisation_id", + get(OrganisationHandler::get).delete(OrganisationHandler::delete), + ) + .route( + "/api/v1/organisation/:organisation_id/campaign", + post(OrganisationHandler::create_campaign), + ) + .route( + "/api/v1/organisation/:organisation_id/campaigns", + get(OrganisationHandler::get_campaigns), + ) + .route( + "/api/v1/organisation/:organisation_id/logo", + patch(OrganisationHandler::update_logo), + ) + .route( + "/api/v1/organisation/:organisation_id/member", + get(OrganisationHandler::get_members) + .put(OrganisationHandler::update_members) + .delete(OrganisationHandler::remove_member), + ) + .route( + "/api/v1/organisation/:organisation_id/admin", + get(OrganisationHandler::get_admins) + .put(OrganisationHandler::update_admins) + .delete(OrganisationHandler::remove_admin), + ) + .route( + "/api/v1/ratings/:rating_id", + get(RatingHandler::get) + .delete(RatingHandler::delete) + .put(RatingHandler::update), + ) + .route( + "/api/v1/:application_id/rating", + post(RatingHandler::create), + ) + .route( + "/api/v1/:application_id/ratings", + get(RatingHandler::get_ratings_for_application), + ) + .route( + "/api/v1/campaign/:campaign_id/role", + post(CampaignHandler::create_role), + ) + .route( + "/api/v1/campaign/:campaign_id/role/:role_id/questions", + get(QuestionHandler::get_all_by_campaign_and_role), + ) + .route( + "/api/v1/campaign/:campaign_id/roles", + get(CampaignHandler::get_roles), + ) + .route( + "/api/v1/campaign/:campaign_id/applications", + get(CampaignHandler::get_applications), + ) + .route( + "/api/v1/role/:role_id", + get(RoleHandler::get) + .put(RoleHandler::update) + .delete(RoleHandler::delete), + ) + .route( + "/api/v1/role/:role_id/applications", + get(RoleHandler::get_applications), + ) + .route( + "/api/v1/campaign/:campaign_id", + get(CampaignHandler::get) + .put(CampaignHandler::update) + .delete(CampaignHandler::delete), + ) + .route("/api/v1/campaign", get(CampaignHandler::get_all)) + .route( + "/api/v1/campaign/:campaign_id/question", + post(QuestionHandler::create), + ) + .route( + "/api/v1/campaign/:campaign_id/question/:id", + patch(QuestionHandler::update).delete(QuestionHandler::delete), + ) + .route( + "/api/v1/campaign/:campaign_id/questions/common", + get(QuestionHandler::get_all_common_by_campaign), + ) + .route( + "/api/v1/campaign/:campaign_id/banner", + patch(CampaignHandler::update_banner), + ) + .route( + "/api/v1/campaign/:campaign_id/application", + post(CampaignHandler::create_application), + ) + .route( + "/api/v1/application/:application_id", + get(ApplicationHandler::get), + ) + .route( + "/api/v1/application/:application_id/status", + patch(ApplicationHandler::set_status), + ) + .route( + "/api/v1/application/:application_id/private", + patch(ApplicationHandler::set_private_status), + ) + .route( + "/api/v1/application/:application_id/answers/common", + get(AnswerHandler::get_all_common_by_application), + ) + .route( + "/api/v1/application/:applicaiton_id/answer", + post(AnswerHandler::create), + ) + .route( + "/api/v1/application/:application_id/answers/role/:role_id", + get(AnswerHandler::get_all_by_application_and_role), + ) + .route( + "/api/v1/answer/:answer_id", + patch(AnswerHandler::update).delete(AnswerHandler::delete), + ) + .with_state(state)) +} diff --git a/backend/server/src/models/application.rs b/backend/server/src/models/application.rs index 65e55d217..1cd9a74f0 100644 --- a/backend/server/src/models/application.rs +++ b/backend/server/src/models/application.rs @@ -1,10 +1,10 @@ use crate::models::error::ChaosError; +use crate::models::user::UserDetails; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use snowflake::SnowflakeIdGenerator; use sqlx::{FromRow, Pool, Postgres, Transaction}; use std::ops::DerefMut; -use crate::models::user::UserDetails; #[derive(Deserialize, Serialize, Clone, FromRow, Debug)] pub struct Application { @@ -41,7 +41,7 @@ pub struct ApplicationDetails { pub user: UserDetails, pub status: ApplicationStatus, pub private_status: ApplicationStatus, - pub applied_roles: Vec + pub applied_roles: Vec, } #[derive(Deserialize, Serialize)] @@ -66,7 +66,6 @@ pub struct ApplicationAppliedRoleDetails { pub role_name: String, } - #[derive(Deserialize, Serialize, sqlx::Type, Clone, Debug)] #[sqlx(type_name = "application_status", rename_all = "PascalCase")] pub enum ApplicationStatus { @@ -116,9 +115,12 @@ impl Application { } /* - Get Application given an application id - */ - pub async fn get(id: i64, transaction: &mut Transaction<'_, Postgres>,) -> Result { + Get Application given an application id + */ + pub async fn get( + id: i64, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result { let application_data = sqlx::query_as!( ApplicationData, " @@ -149,33 +151,32 @@ impl Application { .fetch_all(transaction.deref_mut()) .await?; - Ok( - ApplicationDetails { - id: application_data.id, - campaign_id: application_data.campaign_id, - status: application_data.status, - private_status: application_data.private_status, - applied_roles, - user: UserDetails { - id: application_data.user_id, - email: application_data.user_email, - zid: application_data.user_zid, - name: application_data.user_name, - pronouns: application_data.user_pronouns, - gender: application_data.user_gender, - degree_name: application_data.user_degree_name, - degree_starting_year: application_data.user_degree_starting_year, - }, - } - ) + Ok(ApplicationDetails { + id: application_data.id, + campaign_id: application_data.campaign_id, + status: application_data.status, + private_status: application_data.private_status, + applied_roles, + user: UserDetails { + id: application_data.user_id, + email: application_data.user_email, + zid: application_data.user_zid, + name: application_data.user_name, + pronouns: application_data.user_pronouns, + gender: application_data.user_gender, + degree_name: application_data.user_degree_name, + degree_starting_year: application_data.user_degree_starting_year, + }, + }) } - /* - Get All applications that apply for a given role - */ - pub async fn get_from_role_id(role_id: i64, transaction: &mut Transaction<'_, Postgres>,) - -> Result, ChaosError> { + Get All applications that apply for a given role + */ + pub async fn get_from_role_id( + role_id: i64, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result, ChaosError> { let application_data_list = sqlx::query_as!( ApplicationData, " @@ -205,8 +206,8 @@ impl Application { ", application_data.id ) - .fetch_all(transaction.deref_mut()) - .await?; + .fetch_all(transaction.deref_mut()) + .await?; let details = ApplicationDetails { id: application_data.id, @@ -233,10 +234,12 @@ impl Application { } /* - Get All applications that apply for a given campaign - */ - pub async fn get_from_campaign_id(campaign_id: i64, transaction: &mut Transaction<'_, Postgres>,) - -> Result, ChaosError> { + Get All applications that apply for a given campaign + */ + pub async fn get_from_campaign_id( + campaign_id: i64, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result, ChaosError> { let application_data_list = sqlx::query_as!( ApplicationData, " @@ -250,8 +253,8 @@ impl Application { ", campaign_id ) - .fetch_all(transaction.deref_mut()) - .await?; + .fetch_all(transaction.deref_mut()) + .await?; let mut application_details_list = Vec::new(); for application_data in application_data_list { @@ -286,7 +289,7 @@ impl Application { degree_starting_year: application_data.user_degree_starting_year, }, }; - + application_details_list.push(details) } @@ -294,10 +297,12 @@ impl Application { } /* - Get All applications that are made by a given user - */ - pub async fn get_from_user_id(user_id: i64, transaction: &mut Transaction<'_, Postgres>,) - -> Result, ChaosError> { + Get All applications that are made by a given user + */ + pub async fn get_from_user_id( + user_id: i64, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result, ChaosError> { let application_data_list = sqlx::query_as!( ApplicationData, " @@ -311,8 +316,8 @@ impl Application { ", user_id ) - .fetch_all(transaction.deref_mut()) - .await?; + .fetch_all(transaction.deref_mut()) + .await?; let mut application_details_list = Vec::new(); for application_data in application_data_list { @@ -327,8 +332,8 @@ impl Application { ", application_data.id ) - .fetch_all(transaction.deref_mut()) - .await?; + .fetch_all(transaction.deref_mut()) + .await?; let details = ApplicationDetails { id: application_data.id, @@ -354,36 +359,43 @@ impl Application { Ok(application_details_list) } - pub async fn set_status(id: i64, new_status: ApplicationStatus, pool: &Pool) -> Result<(), ChaosError> { - sqlx::query!( + pub async fn set_status( + id: i64, + new_status: ApplicationStatus, + pool: &Pool, + ) -> Result<(), ChaosError> { + _ = sqlx::query!( " UPDATE applications SET status = $2 - WHERE id = $1; + WHERE id = $1 RETURNING id ", id, new_status as ApplicationStatus ) - .execute(pool) + .fetch_one(pool) .await?; Ok(()) } - pub async fn set_private_status(id: i64, new_status: ApplicationStatus, pool: &Pool) -> Result<(), ChaosError> { - sqlx::query!( + pub async fn set_private_status( + id: i64, + new_status: ApplicationStatus, + pool: &Pool, + ) -> Result<(), ChaosError> { + _ = sqlx::query!( " UPDATE applications SET private_status = $2 - WHERE id = $1; + WHERE id = $1 RETURNING id ", id, new_status as ApplicationStatus ) - .execute(pool) + .fetch_one(pool) .await?; Ok(()) } - -} \ No newline at end of file +} diff --git a/backend/server/src/models/auth.rs b/backend/server/src/models/auth.rs index 89e822775..f28ac9f0c 100644 --- a/backend/server/src/models/auth.rs +++ b/backend/server/src/models/auth.rs @@ -1,12 +1,13 @@ -use std::collections::HashMap; use crate::models::app::AppState; use crate::models::error::ChaosError; -use crate::service::application::user_is_application_admin; +use crate::service::answer::user_is_answer_owner; +use crate::service::application::{user_is_application_admin, user_is_application_owner}; use crate::service::auth::is_super_user; use crate::service::campaign::user_is_campaign_admin; use crate::service::jwt::decode_auth_token; use crate::service::organisation::assert_user_is_organisation_admin; -use crate::service::ratings::{ +use crate::service::question::user_is_question_admin; +use crate::service::rating::{ assert_user_is_application_reviewer_given_rating_id, assert_user_is_organisation_member, assert_user_is_rating_creator_and_organisation_member, }; @@ -17,6 +18,7 @@ use axum::response::{IntoResponse, Redirect, Response}; use axum::{async_trait, RequestPartsExt}; use axum_extra::{headers::Cookie, TypedHeader}; use serde::{Deserialize, Serialize}; +use std::collections::HashMap; // tells the web framework how to take the url query params they will have #[derive(Deserialize, Serialize)] @@ -44,7 +46,7 @@ pub struct AuthUser { pub user_id: i64, } -// extractor - takes a request, and we define what we do to it, +// extractor - takes a request, and we define what we do to it, // returns the struct of the type defined #[async_trait] impl FromRequestParts for AuthUser @@ -146,7 +148,7 @@ where let user_id = claims.sub; let organisation_id = *parts - .extract::>>() + .extract::>>() .await .map_err(|_| ChaosError::BadRequest)? .get("organisation_id") @@ -455,3 +457,129 @@ where Ok(RatingCreator { user_id }) } } + +pub struct QuestionAdmin { + pub user_id: i64, +} + +#[async_trait] +impl FromRequestParts for QuestionAdmin +where + AppState: FromRef, + S: Send + Sync, +{ + type Rejection = ChaosError; + + async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { + let app_state = AppState::from_ref(state); + let decoding_key = &app_state.decoding_key; + let jwt_validator = &app_state.jwt_validator; + let TypedHeader(cookies) = parts + .extract::>() + .await + .map_err(|_| ChaosError::NotLoggedIn)?; + + let token = cookies.get("auth_token").ok_or(ChaosError::NotLoggedIn)?; + + let claims = + decode_auth_token(token, decoding_key, jwt_validator).ok_or(ChaosError::NotLoggedIn)?; + + let pool = &app_state.db; + let user_id = claims.sub; + + let question_id = *parts + .extract::>>() + .await + .map_err(|_| ChaosError::BadRequest)? + .get("question_id") + .ok_or(ChaosError::BadRequest)?; + + user_is_question_admin(user_id, question_id, pool).await?; + + Ok(QuestionAdmin { user_id }) + } +} + +pub struct ApplicationOwner { + pub user_id: i64, +} + +#[async_trait] +impl FromRequestParts for ApplicationOwner +where + AppState: FromRef, + S: Send + Sync, +{ + type Rejection = ChaosError; + + async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { + let app_state = AppState::from_ref(state); + let decoding_key = &app_state.decoding_key; + let jwt_validator = &app_state.jwt_validator; + let TypedHeader(cookies) = parts + .extract::>() + .await + .map_err(|_| ChaosError::NotLoggedIn)?; + + let token = cookies.get("auth_token").ok_or(ChaosError::NotLoggedIn)?; + + let claims = + decode_auth_token(token, decoding_key, jwt_validator).ok_or(ChaosError::NotLoggedIn)?; + + let pool = &app_state.db; + let user_id = claims.sub; + + let application_id = *parts + .extract::>>() + .await + .map_err(|_| ChaosError::BadRequest)? + .get("application_id") + .ok_or(ChaosError::BadRequest)?; + + user_is_application_owner(user_id, application_id, pool).await?; + + Ok(ApplicationOwner { user_id }) + } +} + +pub struct AnswerOwner { + pub user_id: i64, +} + +#[async_trait] +impl FromRequestParts for AnswerOwner +where + AppState: FromRef, + S: Send + Sync, +{ + type Rejection = ChaosError; + + async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { + let app_state = AppState::from_ref(state); + let decoding_key = &app_state.decoding_key; + let jwt_validator = &app_state.jwt_validator; + let TypedHeader(cookies) = parts + .extract::>() + .await + .map_err(|_| ChaosError::NotLoggedIn)?; + + let token = cookies.get("auth_token").ok_or(ChaosError::NotLoggedIn)?; + + let claims = + decode_auth_token(token, decoding_key, jwt_validator).ok_or(ChaosError::NotLoggedIn)?; + + let pool = &app_state.db; + let user_id = claims.sub; + + let application_id = *parts + .extract::>>() + .await + .map_err(|_| ChaosError::BadRequest)? + .get("application_id") + .ok_or(ChaosError::BadRequest)?; + + user_is_answer_owner(user_id, application_id, pool).await?; + + Ok(AnswerOwner { user_id }) + } +} diff --git a/backend/server/src/models/campaign.rs b/backend/server/src/models/campaign.rs index 40590feef..eb750de71 100644 --- a/backend/server/src/models/campaign.rs +++ b/backend/server/src/models/campaign.rs @@ -96,11 +96,11 @@ impl Campaign { update: CampaignUpdate, pool: &Pool, ) -> Result<(), ChaosError> { - sqlx::query!( + _ = sqlx::query!( " UPDATE campaigns SET name = $1, description = $2, starts_at = $3, ends_at = $4 - WHERE id = $5 + WHERE id = $5 RETURNING id ", update.name, update.description, @@ -108,7 +108,7 @@ impl Campaign { update.ends_at, id ) - .execute(pool) + .fetch_one(pool) .await?; Ok(()) @@ -125,17 +125,17 @@ impl Campaign { let image_id = Uuid::new_v4(); let current_time = dt; - sqlx::query!( + _ = sqlx::query!( " UPDATE campaigns SET cover_image = $1, updated_at = $2 - WHERE id = $3 + WHERE id = $3 RETURNING id ", image_id, current_time, id ) - .execute(pool) + .fetch_one(pool) .await?; let upload_url = @@ -146,13 +146,13 @@ impl Campaign { /// Delete a campaign from the database pub async fn delete(id: i64, pool: &Pool) -> Result<(), ChaosError> { - sqlx::query!( + _ = sqlx::query!( " - DELETE FROM campaigns WHERE id = $1 + DELETE FROM campaigns WHERE id = $1 RETURNING id ", id ) - .execute(pool) + .fetch_one(pool) .await?; Ok(()) diff --git a/backend/server/src/models/error.rs b/backend/server/src/models/error.rs index 3a2869e3d..d541562b2 100644 --- a/backend/server/src/models/error.rs +++ b/backend/server/src/models/error.rs @@ -36,6 +36,9 @@ pub enum ChaosError { #[error("S3 error")] StorageError(#[from] s3::error::S3Error), + + #[error("DotEnvy error")] + DotEnvyError(#[from] dotenvy::Error), } /// Implementation for converting errors into responses. Manages error code and message returned. diff --git a/backend/server/src/models/mod.rs b/backend/server/src/models/mod.rs index 1bc24e059..9f30a8bba 100644 --- a/backend/server/src/models/mod.rs +++ b/backend/server/src/models/mod.rs @@ -1,14 +1,13 @@ pub mod answer; pub mod app; +pub mod application; pub mod auth; pub mod campaign; pub mod error; -pub mod question; pub mod organisation; -pub mod ratings; +pub mod question; +pub mod rating; pub mod role; pub mod storage; pub mod transaction; pub mod user; -pub mod application; - diff --git a/backend/server/src/models/organisation.rs b/backend/server/src/models/organisation.rs index 984deef3d..94a34c241 100644 --- a/backend/server/src/models/organisation.rs +++ b/backend/server/src/models/organisation.rs @@ -115,13 +115,13 @@ impl Organisation { } pub async fn delete(id: i64, pool: &Pool) -> Result<(), ChaosError> { - sqlx::query!( + _ = sqlx::query!( " - DELETE FROM organisations WHERE id = $1 + DELETE FROM organisations WHERE id = $1 RETURNING id ", id ) - .execute(pool) + .fetch_one(pool) .await?; Ok(()) @@ -175,6 +175,13 @@ impl Organisation { admin_id_list: Vec, transaction: &mut Transaction<'_, Postgres>, ) -> Result<(), ChaosError> { + let _ = sqlx::query!( + "SELECT id FROM organisations WHERE id = $1", + organisation_id + ) + .fetch_one(transaction.deref_mut()) + .await?; + sqlx::query!( "DELETE FROM organisation_members WHERE organisation_id = $1 AND role = $2", organisation_id, @@ -205,6 +212,13 @@ impl Organisation { member_id_list: Vec, transaction: &mut Transaction<'_, Postgres>, ) -> Result<(), ChaosError> { + let _ = sqlx::query!( + "SELECT id FROM organisations WHERE id = $1", + organisation_id + ) + .fetch_one(transaction.deref_mut()) + .await?; + sqlx::query!( "DELETE FROM organisation_members WHERE organisation_id = $1 AND role = $2", organisation_id, @@ -233,8 +247,15 @@ impl Organisation { pub async fn remove_admin( organisation_id: i64, admin_to_remove: i64, - pool: &Pool, + transaction: &mut Transaction<'_, Postgres>, ) -> Result<(), ChaosError> { + let _ = sqlx::query!( + "SELECT id FROM organisations WHERE id = $1", + organisation_id + ) + .fetch_one(transaction.deref_mut()) + .await?; + sqlx::query!( " UPDATE organisation_members SET role = $3 WHERE user_id = $1 AND organisation_id = $2 @@ -243,7 +264,7 @@ impl Organisation { organisation_id, OrganisationRole::User as OrganisationRole ) - .execute(pool) + .execute(transaction.deref_mut()) .await?; Ok(()) @@ -252,8 +273,15 @@ impl Organisation { pub async fn remove_member( organisation_id: i64, user_id: i64, - pool: &Pool, + transaction: &mut Transaction<'_, Postgres>, ) -> Result<(), ChaosError> { + let _ = sqlx::query!( + "SELECT id FROM organisations WHERE id = $1", + organisation_id + ) + .fetch_one(transaction.deref_mut()) + .await?; + sqlx::query!( " DELETE FROM organisation_members WHERE user_id = $1 AND organisation_id = $2 @@ -261,7 +289,7 @@ impl Organisation { user_id, organisation_id ) - .execute(pool) + .execute(transaction.deref_mut()) .await?; Ok(()) @@ -276,17 +304,17 @@ impl Organisation { let logo_id = Uuid::new_v4(); let current_time = dt; - sqlx::query!( + _ = sqlx::query!( " UPDATE organisations SET logo = $2, updated_at = $3 - WHERE id = $1 + WHERE id = $1 RETURNING id ", id, logo_id, current_time ) - .execute(pool) + .fetch_one(pool) .await?; let upload_url = diff --git a/backend/server/src/models/question.rs b/backend/server/src/models/question.rs index 27eb5e854..db1f70f36 100644 --- a/backend/server/src/models/question.rs +++ b/backend/server/src/models/question.rs @@ -1,8 +1,9 @@ use crate::models::error::ChaosError; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; -use sqlx::{Pool, Postgres, QueryBuilder, Row}; use snowflake::SnowflakeIdGenerator; +use sqlx::{Postgres, QueryBuilder, Transaction}; +use std::ops::DerefMut; /// The `Question` type that will be sent in API responses. /// @@ -53,6 +54,397 @@ pub struct Question { updated_at: DateTime, } +#[derive(Deserialize)] +pub struct NewQuestion { + pub title: String, + pub description: Option, + pub common: bool, + pub roles: Option>, + pub required: bool, + + #[serde(flatten)] + pub question_data: QuestionData, +} + +#[derive(Deserialize, sqlx::FromRow)] +pub struct QuestionRawData { + id: i64, + title: String, + description: Option, + common: bool, // Common question are shown at the start + required: bool, + + question_type: QuestionType, + multi_option_data: Option>>, + + created_at: DateTime, + updated_at: DateTime, +} + +impl Question { + pub async fn create( + campaign_id: i64, + title: String, + description: Option, + common: bool, + roles: Option>, + required: bool, + question_data: QuestionData, + mut snowflake_generator: SnowflakeIdGenerator, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result { + question_data.validate()?; + + let id = snowflake_generator.generate(); + + sqlx::query!( + " + INSERT INTO questions ( + id, title, description, common, + required, question_type, campaign_id + ) VALUES ($1, $2, $3, $4, $5, $6, $7) + ", + id, + title, + description, + common, + required, + QuestionType::from_question_data(&question_data) as QuestionType, + campaign_id + ) + .execute(transaction.deref_mut()) + .await?; + + question_data + .insert_into_db(id, transaction, snowflake_generator) + .await?; + + if !common { + for role in roles.expect("Should be !None if !common") { + sqlx::query!( + " + INSERT INTO question_roles (question_id, role_id) VALUES ($1, $2) + ", + id, + role + ) + .execute(transaction.deref_mut()) + .await?; + } + } + + Ok(id) + } + + pub async fn get( + id: i64, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result { + let question_raw_data: QuestionRawData = sqlx::query_as( + " + SELECT + q.id, + q.title, + q.description, + q.common, + q.required, + q.question_type AS \"question_type: QuestionType\", + q.created_at, + q.updated_at, + array_agg( + jsonb_build_object( + 'id', mod.id, + 'display_order', mod.display_order, + 'text', mod.text + ) ORDER BY mod.display_order + ) FILTER (WHERE mod.id IS NOT NULL) AS \"multi_option_data: Option>>\" + FROM + questions q + LEFT JOIN + multi_option_question_options mod ON q.id = mod.question_id + AND q.question_type IN ('MultiChoice', 'MultiSelect', 'DropDown', 'Ranking') + WHERE q.id = $1 + GROUP BY + q.id + " + ) + .bind(id) + .fetch_one(transaction.deref_mut()) + .await?; + + let question_data = QuestionData::from_question_raw_data( + question_raw_data.question_type, + question_raw_data.multi_option_data, + ); + + Ok(Question { + id, + title: question_raw_data.title, + description: question_raw_data.description, + common: question_raw_data.common, + required: question_raw_data.required, + question_data, + created_at: question_raw_data.created_at, + updated_at: question_raw_data.updated_at, + }) + } + + pub async fn get_all_by_campaign( + campaign_id: i64, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result, ChaosError> { + let question_raw_data: Vec = sqlx::query_as( + " + SELECT + q.id, + q.title, + q.description, + q.common, + q.required, + q.question_type AS \"question_type: QuestionType\", + q.created_at, + q.updated_at, + array_agg( + jsonb_build_object( + 'id', mod.id, + 'display_order', mod.display_order, + 'text', mod.text + ) ORDER BY mod.display_order + ) FILTER (WHERE mod.id IS NOT NULL) AS \"multi_option_data: Option>>\" + FROM + questions q + LEFT JOIN + multi_option_question_options mod ON q.id = mod.question_id + AND q.question_type IN ('MultiChoice', 'MultiSelect', 'DropDown', 'Ranking') + WHERE q.campaign_id = $1 + GROUP BY + q.id + " + ) + .bind(campaign_id) + .fetch_all(transaction.deref_mut()) + .await?; + + let questions = question_raw_data + .into_iter() + .map(|question_raw_data| { + let question_data = QuestionData::from_question_raw_data( + question_raw_data.question_type, + question_raw_data.multi_option_data, + ); + + Question { + id: question_raw_data.id, + title: question_raw_data.title, + description: question_raw_data.description, + common: question_raw_data.common, + required: question_raw_data.required, + question_data, + created_at: question_raw_data.created_at, + updated_at: question_raw_data.updated_at, + } + }) + .collect(); + + Ok(questions) + } + + pub async fn get_all_by_campaign_and_role( + campaign_id: i64, + role_id: i64, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result, ChaosError> { + let question_raw_data: Vec = sqlx::query_as( + " + SELECT + q.id, + q.title, + q.description, + q.common, + q.required, + q.question_type AS \"question_type: QuestionType\", + q.created_at, + q.updated_at, + array_agg( + jsonb_build_object( + 'id', mod.id, + 'display_order', mod.display_order, + 'text', mod.text + ) ORDER BY mod.display_order + ) FILTER (WHERE mod.id IS NOT NULL) AS \"multi_option_data: Option>>\" + FROM + questions q + JOIN + question_roles qr ON q.id = qr.question_id + LEFT JOIN + multi_option_question_options mod ON q.id = mod.question_id + AND q.question_type IN ('MultiChoice', 'MultiSelect', 'DropDown', 'Ranking') + WHERE q.campaign_id = $1 AND q.common = true AND qr.role_id = $2 + GROUP BY + q.id + " + ) + .bind(campaign_id) + .bind(role_id) + .fetch_all(transaction.deref_mut()) + .await?; + + let questions = question_raw_data + .into_iter() + .map(|question_raw_data| { + let question_data = QuestionData::from_question_raw_data( + question_raw_data.question_type, + question_raw_data.multi_option_data, + ); + + Question { + id: question_raw_data.id, + title: question_raw_data.title, + description: question_raw_data.description, + common: question_raw_data.common, + required: question_raw_data.required, + question_data, + created_at: question_raw_data.created_at, + updated_at: question_raw_data.updated_at, + } + }) + .collect(); + + Ok(questions) + } + + pub async fn get_all_common_by_campaign( + campaign_id: i64, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result, ChaosError> { + let question_raw_data: Vec = sqlx::query_as( + " + SELECT + q.id, + q.title, + q.description, + q.common, + q.required, + q.question_type AS \"question_type: QuestionType\", + q.created_at, + q.updated_at, + array_agg( + jsonb_build_object( + 'id', mod.id, + 'display_order', mod.display_order, + 'text', mod.text + ) ORDER BY mod.display_order + ) FILTER (WHERE mod.id IS NOT NULL) AS \"multi_option_data: Option>>\" + FROM + questions q + LEFT JOIN + multi_option_question_options mod ON q.id = mod.question_id + AND q.question_type IN ('MultiChoice', 'MultiSelect', 'DropDown', 'Ranking') + WHERE q.campaign_id = $1 AND q.common = true + GROUP BY + q.id + " + ) + .bind(campaign_id) + .fetch_all(transaction.deref_mut()) + .await?; + + let questions = question_raw_data + .into_iter() + .map(|question_raw_data| { + let question_data = QuestionData::from_question_raw_data( + question_raw_data.question_type, + question_raw_data.multi_option_data, + ); + + Question { + id: question_raw_data.id, + title: question_raw_data.title, + description: question_raw_data.description, + common: question_raw_data.common, + required: question_raw_data.required, + question_data, + created_at: question_raw_data.created_at, + updated_at: question_raw_data.updated_at, + } + }) + .collect(); + + Ok(questions) + } + + pub async fn update( + id: i64, + title: String, + description: Option, + common: bool, + roles: Option>, + required: bool, + question_data: QuestionData, + transaction: &mut Transaction<'_, Postgres>, + snowflake_generator: SnowflakeIdGenerator, + ) -> Result<(), ChaosError> { + question_data.validate()?; + + let question_type_parent: QuestionTypeParent = sqlx::query_as!( + QuestionTypeParent, + " + UPDATE questions SET + title = $2, description = $3, common = $4, + required = $5, question_type = $6, updated_at = $7 + WHERE id = $1 + RETURNING question_type AS \"question_type: QuestionType\" + ", + id, + title, + description, + common, + required, + QuestionType::from_question_data(&question_data) as QuestionType, + Utc::now() + ) + .fetch_one(transaction.deref_mut()) + .await?; + + let old_data = QuestionData::from_question_type(&question_type_parent.question_type); + old_data.delete_from_db(id, transaction).await?; + + question_data + .insert_into_db(id, transaction, snowflake_generator) + .await?; + + sqlx::query!("DELETE FROM question_roles WHERE question_id = $1", id) + .execute(transaction.deref_mut()) + .await?; + if !common { + for role in roles.expect("Should be !None if !common") { + sqlx::query!( + " + INSERT INTO question_roles (question_id, role_id) VALUES ($1, $2) + ", + id, + role + ) + .execute(transaction.deref_mut()) + .await?; + } + } + + Ok(()) + } + + pub async fn delete( + id: i64, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result<(), ChaosError> { + sqlx::query!("DELETE FROM questions WHERE id = $1 RETURNING id", id) + .fetch_one(transaction.deref_mut()) + .await?; + + Ok(()) + } +} + /// An enum that represents all the data types of question data that CHAOS can handle. /// This stores all the data for each question type. /// @@ -70,23 +462,99 @@ pub enum QuestionData { Ranking(MultiOptionData), } +/// An enum needed to track QuestionType in the database, +/// as DB enum does not contain the inner data. +#[derive(Deserialize, Serialize, PartialEq, sqlx::Type)] +#[sqlx(type_name = "question_type", rename_all = "PascalCase")] +pub enum QuestionType { + ShortAnswer, + MultiChoice, + MultiSelect, + DropDown, + Ranking, +} + +#[derive(Deserialize)] +pub struct QuestionTypeParent { + pub question_type: QuestionType, +} + +impl QuestionType { + fn from_question_data(question_data: &QuestionData) -> Self { + match question_data { + QuestionData::ShortAnswer => QuestionType::ShortAnswer, + QuestionData::MultiChoice(_) => QuestionType::MultiChoice, + QuestionData::MultiSelect(_) => QuestionType::MultiSelect, + QuestionData::DropDown(_) => QuestionType::DropDown, + QuestionData::Ranking(_) => QuestionType::Ranking, + } + } +} + #[derive(Deserialize, Serialize)] pub struct MultiOptionData { options: Vec, } +impl Default for MultiOptionData { + fn default() -> Self { + Self { + // Return an empty vector to be replaced by real data later on. + options: vec![], + } + } +} + /// Each of these structs represent a row in the `multi_option_question_options` /// table. For a `MultiChoice` question like "What is your favourite programming /// language?", there would be rows for "Rust", "Java" and "TypeScript". #[derive(Deserialize, Serialize)] pub struct MultiOptionQuestionOption { - id: i32, + id: i64, display_order: i32, text: String, } impl QuestionData { - pub async fn validate(self) -> Result<(), ChaosError> { + fn from_question_type(question_type: &QuestionType) -> Self { + match question_type { + QuestionType::ShortAnswer => QuestionData::ShortAnswer, + QuestionType::MultiChoice => QuestionData::MultiChoice(MultiOptionData::default()), + QuestionType::MultiSelect => QuestionData::MultiSelect(MultiOptionData::default()), + QuestionType::DropDown => QuestionData::DropDown(MultiOptionData::default()), + QuestionType::Ranking => QuestionData::Ranking(MultiOptionData::default()), + } + } + + fn from_question_raw_data( + question_type: QuestionType, + multi_option_data: Option>>, + ) -> Self { + return if question_type == QuestionType::ShortAnswer { + QuestionData::ShortAnswer + } else if question_type == QuestionType::MultiChoice + || question_type == QuestionType::MultiSelect + || question_type == QuestionType::DropDown + || question_type == QuestionType::Ranking + { + let options = multi_option_data + .expect("Data should exist for MultiOptionData variants") + .0; + let data = MultiOptionData { options }; + + match question_type { + QuestionType::MultiChoice => QuestionData::MultiChoice(data), + QuestionType::MultiSelect => QuestionData::MultiSelect(data), + QuestionType::DropDown => QuestionData::DropDown(data), + QuestionType::Ranking => QuestionData::Ranking(data), + _ => QuestionData::ShortAnswer, // Should never be reached, hence return ShortAnswer + } + } else { + QuestionData::ShortAnswer // Should never be reached, hence return ShortAnswer + }; + } + + pub fn validate(&self) -> Result<(), ChaosError> { match self { Self::ShortAnswer => Ok(()), Self::MultiChoice(data) @@ -102,7 +570,12 @@ impl QuestionData { } } - pub async fn insert_into_db(self, question_id: i64, pool: &Pool, mut snowflake_generator: SnowflakeIdGenerator) -> Result<(), ChaosError> { + pub async fn insert_into_db( + self, + question_id: i64, + transaction: &mut Transaction<'_, Postgres>, + mut snowflake_generator: SnowflakeIdGenerator, + ) -> Result<(), ChaosError> { match self { Self::ShortAnswer => Ok(()), Self::MultiChoice(data) @@ -114,11 +587,34 @@ impl QuestionData { query_builder.push_values(data.options, |mut b, option| { let id = snowflake_generator.real_time_generate(); - b.push_bind(id).push_bind(option.text).push_bind(question_id).push_bind(option.display_order); + b.push_bind(id) + .push_bind(option.text) + .push_bind(question_id) + .push_bind(option.display_order); }); let query = query_builder.build(); - let result = query.execute(pool).await?; + query.execute(transaction.deref_mut()).await?; + + Ok(()) + } + } + } + + pub async fn delete_from_db( + self, + question_id: i64, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result<(), ChaosError> { + match self { + Self::ShortAnswer => Ok(()), + Self::MultiChoice(_) | Self::MultiSelect(_) | Self::DropDown(_) | Self::Ranking(_) => { + sqlx::query!( + "DELETE FROM multi_option_question_options WHERE question_id = $1", + question_id + ) + .execute(transaction.deref_mut()) + .await?; Ok(()) } diff --git a/backend/server/src/models/ratings.rs b/backend/server/src/models/rating.rs similarity index 96% rename from backend/server/src/models/ratings.rs rename to backend/server/src/models/rating.rs index de01838fa..8a8c2f383 100644 --- a/backend/server/src/models/ratings.rs +++ b/backend/server/src/models/rating.rs @@ -18,7 +18,6 @@ pub struct Rating { #[derive(Deserialize, Serialize)] pub struct NewRating { - pub rater_user_id: i64, pub rating: i32, pub comment: Option, } @@ -43,11 +42,11 @@ impl Rating { pub async fn create( new_rating: NewRating, application_id: i64, + rater_id: i64, mut snowflake_generator: SnowflakeIdGenerator, transaction: &mut Transaction<'_, Postgres>, ) -> Result<(), ChaosError> { let rating_id = snowflake_generator.generate(); - let rater_user_id = new_rating.rater_user_id; let rating = new_rating.rating; let comment = new_rating.comment; @@ -58,7 +57,7 @@ impl Rating { ", rating_id, application_id, - rater_user_id, + rater_id, rating, comment ) @@ -83,7 +82,7 @@ impl Rating { UPDATE application_ratings SET rating = $2, comment = $3, updated_at = $4 WHERE id = $1 - RETURNING id; + RETURNING id ", rating_id, rating, @@ -145,7 +144,7 @@ impl Rating { let _ = sqlx::query!( " DELETE FROM application_ratings WHERE id = $1 - RETURNING id; + RETURNING id ", rating_id ) diff --git a/backend/server/src/models/role.rs b/backend/server/src/models/role.rs index a52eb1d4d..ff53014b8 100644 --- a/backend/server/src/models/role.rs +++ b/backend/server/src/models/role.rs @@ -82,13 +82,13 @@ impl Role { } pub async fn delete(id: i64, pool: &Pool) -> Result<(), ChaosError> { - sqlx::query!( + let _ = sqlx::query!( " - DELETE FROM campaign_roles WHERE id = $1 + DELETE FROM campaign_roles WHERE id = $1 RETURNING id ", id ) - .execute(pool) + .fetch_one(pool) .await?; Ok(()) @@ -99,11 +99,11 @@ impl Role { role_data: RoleUpdate, pool: &Pool, ) -> Result<(), ChaosError> { - sqlx::query!( + let _ = sqlx::query!( " UPDATE campaign_roles SET (name, description, min_available, max_available, finalised) = ($2, $3, $4, $5, $6) - WHERE id = $1; + WHERE id = $1 RETURNING id ", id, role_data.name, @@ -112,7 +112,7 @@ impl Role { role_data.max_avaliable, role_data.finalised ) - .execute(pool) + .fetch_one(pool) .await?; Ok(()) diff --git a/backend/server/src/models/user.rs b/backend/server/src/models/user.rs index 19009a1f0..cf5fb8e4f 100644 --- a/backend/server/src/models/user.rs +++ b/backend/server/src/models/user.rs @@ -1,6 +1,6 @@ +use crate::models::error::ChaosError; use serde::{Deserialize, Serialize}; use sqlx::{FromRow, Pool, Postgres}; -use crate::models::error::ChaosError; #[derive(Deserialize, Serialize, sqlx::Type, Clone)] #[sqlx(type_name = "user_role", rename_all = "PascalCase")] @@ -63,56 +63,68 @@ pub struct UserDegree { impl User { pub async fn get(id: i64, pool: &Pool) -> Result { let user = sqlx::query_as!( - User, - r#" + User, + r#" SELECT id, email, zid, name, pronouns, gender, degree_name, degree_starting_year, role AS "role!: UserRole" FROM users WHERE id = $1 "#, - id - ) + id + ) .fetch_one(pool) .await?; Ok(user) } - pub async fn update_name(id: i64, name: String, pool: &Pool) -> Result<(), ChaosError> { + pub async fn update_name( + id: i64, + name: String, + pool: &Pool, + ) -> Result<(), ChaosError> { let _ = sqlx::query!( - " + " UPDATE users SET name = $1 WHERE id = $2 RETURNING id ", - name, - id - ) + name, + id + ) .fetch_one(pool) .await?; Ok(()) } - pub async fn update_pronouns(id: i64, pronouns: String, pool: &Pool) -> Result<(), ChaosError> { + pub async fn update_pronouns( + id: i64, + pronouns: String, + pool: &Pool, + ) -> Result<(), ChaosError> { let _ = sqlx::query!( - " + " UPDATE users SET pronouns = $1 WHERE id = $2 RETURNING id ", - pronouns, - id - ) + pronouns, + id + ) .fetch_one(pool) .await?; Ok(()) } - pub async fn update_gender(id: i64, gender: String, pool: &Pool) -> Result<(), ChaosError> { + pub async fn update_gender( + id: i64, + gender: String, + pool: &Pool, + ) -> Result<(), ChaosError> { let _ = sqlx::query!( - " + " UPDATE users SET gender = $1 WHERE id = $2 RETURNING id ", - gender, - id - ) + gender, + id + ) .fetch_one(pool) .await?; @@ -121,12 +133,12 @@ impl User { pub async fn update_zid(id: i64, zid: String, pool: &Pool) -> Result<(), ChaosError> { let _ = sqlx::query!( - " + " UPDATE users SET zid = $1 WHERE id = $2 RETURNING id ", - zid, - id - ) + zid, + id + ) .fetch_one(pool) .await?; @@ -140,13 +152,13 @@ impl User { pool: &Pool, ) -> Result<(), ChaosError> { let _ = sqlx::query!( - " + " UPDATE users SET degree_name = $1, degree_starting_year = $2 WHERE id = $3 RETURNING id ", - degree_name, - degree_starting_year, - id - ) + degree_name, + degree_starting_year, + id + ) .fetch_one(pool) .await?; diff --git a/backend/server/src/service/answer.rs b/backend/server/src/service/answer.rs new file mode 100644 index 000000000..682656a09 --- /dev/null +++ b/backend/server/src/service/answer.rs @@ -0,0 +1,32 @@ +use crate::models::error::ChaosError; +use sqlx::{Pool, Postgres}; + +pub async fn user_is_answer_owner( + user_id: i64, + answer_id: i64, + pool: &Pool, +) -> Result<(), ChaosError> { + let is_owner = sqlx::query!( + " + SELECT EXISTS( + SELECT 1 FROM ( + SELECT FROM answers ans + JOIN applications app ON ans.application_id = app.id + WHERE ans.id = $1 AND app.user_id = $2 + ) + ) + ", + answer_id, + user_id + ) + .fetch_one(pool) + .await? + .exists + .expect("`exists` should always exist in this query result"); + + if !is_owner { + return Err(ChaosError::Unauthorized); + } + + Ok(()) +} diff --git a/backend/server/src/service/application.rs b/backend/server/src/service/application.rs index 4fdf052be..dcdf755b7 100644 --- a/backend/server/src/service/application.rs +++ b/backend/server/src/service/application.rs @@ -1,7 +1,6 @@ use crate::models::error::ChaosError; use sqlx::{Pool, Postgres}; - pub async fn user_is_application_admin( user_id: i64, application_id: i64, @@ -32,5 +31,32 @@ pub async fn user_is_application_admin( } Ok(()) +} + +pub async fn user_is_application_owner( + user_id: i64, + application_id: i64, + pool: &Pool, +) -> Result<(), ChaosError> { + let is_owner = sqlx::query!( + " + SELECT EXISTS( + SELECT 1 FROM ( + SELECT FROM applications WHERE id = $1 AND user_id = $2 + ) + ) + ", + application_id, + user_id + ) + .fetch_one(pool) + .await? + .exists + .expect("`exists` should always exist in this query result"); -} \ No newline at end of file + if !is_owner { + return Err(ChaosError::Unauthorized); + } + + Ok(()) +} diff --git a/backend/server/src/service/mod.rs b/backend/server/src/service/mod.rs index 2e0836227..8fd957f68 100644 --- a/backend/server/src/service/mod.rs +++ b/backend/server/src/service/mod.rs @@ -1,8 +1,10 @@ +pub mod answer; +pub mod application; pub mod auth; pub mod campaign; pub mod jwt; pub mod oauth2; pub mod organisation; -pub mod ratings; +pub mod question; +pub mod rating; pub mod role; -pub mod application; diff --git a/backend/server/src/service/question.rs b/backend/server/src/service/question.rs new file mode 100644 index 000000000..7dc412137 --- /dev/null +++ b/backend/server/src/service/question.rs @@ -0,0 +1,32 @@ +use crate::models::error::ChaosError; +use sqlx::{Pool, Postgres}; + +pub async fn user_is_question_admin( + user_id: i64, + question_id: i64, + pool: &Pool, +) -> Result<(), ChaosError> { + let is_admin = sqlx::query!( + " + SELECT EXISTS( + SELECT 1 + FROM questions q + JOIN campaigns c on q.campaign_id = c.id + JOIN organisation_members om on c.organisation_id = om.organisation_id + WHERE q.id = $1 AND om.user_id = $2 AND om.role = 'Admin' + ) + ", + question_id, + user_id + ) + .fetch_one(pool) + .await? + .exists + .expect("`exists` should always exist in this query result"); + + if !is_admin { + return Err(ChaosError::Unauthorized); + } + + Ok(()) +} diff --git a/backend/server/src/service/ratings.rs b/backend/server/src/service/rating.rs similarity index 93% rename from backend/server/src/service/ratings.rs rename to backend/server/src/service/rating.rs index 0ff6b0951..0d2dfe60d 100644 --- a/backend/server/src/service/ratings.rs +++ b/backend/server/src/service/rating.rs @@ -1,11 +1,5 @@ -use crate::models::campaign::Campaign; use crate::models::error::ChaosError; -use crate::models::organisation::{Member, MemberList, OrganisationDetails, OrganisationRole}; -use chrono::{DateTime, Utc}; -use snowflake::SnowflakeIdGenerator; -use sqlx::{Pool, Postgres, Transaction}; -use std::ops::DerefMut; -use uuid::Uuid; +use sqlx::{Pool, Postgres}; /// Any member of the organisation that owns the campaign is an application /// viewer, because all members are either directors or execs (TODO: might be From 088a48e3ba3ec4cca18ca730bea15fbd34ed8eb6 Mon Sep 17 00:00:00 2001 From: Alex Miao <79033892+AlexMIaoPU@users.noreply.github.com> Date: Sat, 23 Nov 2024 16:41:13 +1100 Subject: [PATCH 36/56] Chaos 475 api documentation (#523) * feat(docs): updates to user and organisation api spec * feat(docs): draft spec for campaign api * fix(ci): update rust workflow to use actions/cache * rewrite API yamal file using components/schema up to /api/v1/role/:role_id * rewrite API yamal file using components/schema up to /api/v1/role/:role_id I guess * rewrite API yamal file using components/schema up to /api/v1/role/:role_id I guess * finished API doc * Update rust.yml --------- Co-authored-by: Kavika Co-authored-by: Alex_Miao_WSL --- backend/api.yaml | 794 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 746 insertions(+), 48 deletions(-) diff --git a/backend/api.yaml b/backend/api.yaml index 8b3f9ef20..729d40303 100644 --- a/backend/api.yaml +++ b/backend/api.yaml @@ -136,6 +136,12 @@ paths: name: type: string example: Clancy Lion + pronouns: + type: string + example: They/Them + gender: + type: string + example: Male degree_name: type: string example: Computer Science @@ -185,6 +191,77 @@ paths: error: type: string example: Not logged in. + + /user/pronouns: + patch: + operationId: updateUserPronouns + description: Updates currently logged in user's pronouns. + tags: + - User + requestBody: + required: true + content: + application/json: + schema: + properties: + zid: + type: string + example: "z5123456" + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + message: + type: string + example: Successfully updated pronouns. + '401': + description: Not logged in. + content: + application/json: + schema: + properties: + error: + type: string + example: Not logged in. + /user/gender: + patch: + operationId: updateUserGender + description: Updates currently logged in user's gender. + tags: + - User + requestBody: + required: true + content: + application/json: + schema: + properties: + zid: + type: string + example: "z5123456" + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + message: + type: string + example: Successfully updated gender. + '401': + description: Not logged in. + content: + application/json: + schema: + properties: + error: + type: string + example: Not logged in. + + /user/zid: patch: operationId: updateUserZid @@ -256,6 +333,36 @@ paths: error: type: string example: Not logged in. + + /user/applications: + get: + operationId: getUserApplications + description: Returns info about applications made by currently logged in user. + tags: + - User + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + campaigns: + type: array + items: + $ref: '#/components/schemas/ApplicationDetails' + '401': + description: Not logged in. + content: + application/json: + schema: + properties: + error: + type: string + example: Not logged in. + + + /organisation: post: operationId: createOrganisation @@ -329,6 +436,15 @@ paths: created_at: type: string example: 2024-02-10T18:25:43.511Z + '401': + description: Not logged in. + content: + application/json: + schema: + properties: + error: + type: string + example: Not logged in. delete: operationId: deleteOrganisationById parameters: @@ -352,6 +468,15 @@ paths: message: type: string example: Successfully deleted organisation. + '401': + description: Not logged in. + content: + application/json: + schema: + properties: + error: + type: string + example: Not logged in. '403': description: User is not a super user. content: @@ -385,27 +510,17 @@ paths: campaigns: type: array items: - type: object - properties: - id: - type: integer - format: int64 - example: 6996987893965262849 - name: - type: string - example: 2024 Subcommittee Recruitment - cover_image: - type: string - example: 2d19617b-46fd-4927-9f53-77d69232ba5d - description: - type: string - example: Are you excited to make a difference? - starts_at: - type: string - example: 2024-03-15T18:25:43.511Z - ends_at: - type: string - example: 2024-04-15T18:25:43.511Z + $ref: '#/components/schemas/OrganisationCampaign' + '401': + description: Not logged in. + content: + application/json: + schema: + properties: + error: + type: string + example: Not logged in. + /organisation/{id}/logo: patch: operationId: updateOrganisationLogoById @@ -430,7 +545,7 @@ paths: upload_url: type: string description: Presigned S3 url to upload file. - example: https://presignedurldemo.s3.eu-west-2.amazonaws.com/6996987893965262849/2d19617b-46fd-4927-9f53-77d69232ba5d?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJJWZ7B6WCRGMKFGQ%2F20180210%2Feu-west-2%2Fs3%2Faws4_request&X-Amz-Date=20180210T171315Z&X-Amz-Expires=1800&X-Amz-Signature=12b74b0788aa036bc7c3d03b3f20c61f1f91cc9ad8873e3314255dc479a25351&X-Amz-SignedHeaders=host + example: https://www.youtube.com/watch?v=dQw4w9WgXcQ '401': description: Not logged in. content: @@ -449,7 +564,8 @@ paths: error: type: string example: Unauthorized - /organisation/{id}/members: + + /organisation/{id}/member: get: operationId: getOrganisationMembersById parameters: @@ -540,7 +656,207 @@ paths: type: string example: Not logged in. '403': - description: User is not an organisation admin. + description: User is not an organisation admin. + content: + application/json: + schema: + properties: + error: + type: string + example: Unauthorized + delete: + operationId: deleteOrganisationMemberById + parameters: + - name: id + in: path + description: Organisation ID + required: true + schema: + type: integer + format: int64 + requestBody: + required: true + content: + application/json: + schema: + properties: + user_id: + type: integer + format: int64 + description: Specifies member for deletion in organistion. + tags: + - Organisation + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + message: + type: string + example: Successfully updated members. + '401': + description: Not logged in. + content: + application/json: + schema: + properties: + error: + type: string + example: Not logged in. + '403': + description: User is not an organisation admin. + content: + application/json: + schema: + properties: + error: + type: string + example: Unauthorized + + /organisation/{id}/admin: + get: + operationId: getOrganisationAdminsById + parameters: + - name: id + in: path + description: Organisation ID + required: true + schema: + type: integer + format: int64 + description: Returns list of admins of specified organisation. + tags: + - Organisation + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + members: + type: array + items: + type: object + properties: + id: + type: integer + format: int64 + example: 1541815603606036480 + name: + type: string + example: Clancy Lion + role: + type: string + example: Admin + '403': + description: User is not a SuperUser. + content: + application/json: + schema: + properties: + error: + type: string + example: Unauthorized + put: + operationId: updateOrganisationAdminsById + parameters: + - name: id + in: path + description: Organisation ID + required: true + schema: + type: integer + format: int64 + requestBody: + required: true + content: + application/json: + schema: + properties: + members: + type: array + uniqueItems: true + items: + type: integer + format: int64 + example: [1541815603606036480, 1541815603606036827, 1541815287306036429] + description: Specifies Admins for specified organistion. + tags: + - Organisation + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + message: + type: string + example: Successfully updated members. + '401': + description: Not logged in. + content: + application/json: + schema: + properties: + error: + type: string + example: Not logged in. + '403': + description: User is not a SuperUser. + content: + application/json: + schema: + properties: + error: + type: string + example: Unauthorized + delete: + operationId: deleteOrganisationAdminById + parameters: + - name: id + in: path + description: Organisation ID + required: true + schema: + type: integer + format: int64 + requestBody: + required: true + content: + application/json: + schema: + properties: + user_id: + type: integer + format: int64 + description: Specifies Admin for deletion in organistion. + tags: + - Organisation + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + message: + type: string + example: Successfully deleted Admin. + '401': + description: Not logged in. + content: + application/json: + schema: + properties: + error: + type: string + example: Not logged in. + '403': + description: User is not a SuperUser. content: application/json: schema: @@ -548,6 +864,7 @@ paths: error: type: string example: Unauthorized + /organisation/{id}/campaign: post: operationId: createCampaign @@ -805,7 +1122,7 @@ paths: upload_url: type: string description: Presigned S3 url to upload file. - example: https://presignedurldemo.s3.eu-west-2.amazonaws.com/6996987893965262849/2d19617b-46fd-4927-9f53-77d69232ba5d?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJJWZ7B6WCRGMKFGQ%2F20180210%2Feu-west-2%2Fs3%2Faws4_request&X-Amz-Date=20180210T171315Z&X-Amz-Expires=1800&X-Amz-Signature=12b74b0788aa036bc7c3d03b3f20c61f1f91cc9ad8873e3314255dc479a25351&X-Amz-SignedHeaders=host + example: https://www.youtube.com/watch?v=dQw4w9WgXcQ '401': description: Not logged in. content: @@ -906,24 +1223,71 @@ paths: campaigns: type: array items: - type: object - properties: - name: - type: string - example: Chief Mouser - description: - type: string - example: Larry the cat gone missing! now we need someone else to handle the rat issues at 10th Downing st. - min_available: - type: int32 - example: 1 - max_available: - type: int32 - example: 3 - finalised: - type: boolean - description: Whether this role has been finalised (e.g. max avaliable number) - example: False + $ref: '#components/schemas/RoleDetails' + '401': + description: Not logged in. + content: + application/json: + schema: + properties: + error: + type: string + example: Not logged in. + '403': + description: User is not a Campaign Admin. + content: + application/json: + schema: + properties: + error: + type: string + example: Unauthorized + + /campaign/{id}/applications: + get: + operationId: getApplicationsById + parameters: + - name: id + in: path + description: campaign ID + required: true + schema: + type: integer + format: int64 + description: Returns info about all Applications in given Campaign. + tags: + - Campaign + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + applications: + type: array + items: + $ref: '#components/schemas/ApplicationDetails' + '401': + description: Not logged in. + content: + application/json: + schema: + properties: + error: + type: string + example: Not logged in. + '403': + description: User is not a Campaign Admin. + content: + application/json: + schema: + properties: + error: + type: string + example: Unauthorized + + /role/{id}: get: operationId: getRoleById @@ -934,7 +1298,7 @@ paths: required: true schema: type: integer - format: int32 + format: int64 description: Returns info about specified role. tags: - Role @@ -973,14 +1337,14 @@ paths: put: operationId: updateRoleById - parameters: + parameters: - name: id in: path description: Role ID required: true schema: type: integer - format: int32 + format: int64 description: Update a role given the role id. tags: - Role @@ -1017,6 +1381,15 @@ paths: message: type: string example: Successfully update organisation. + '401': + description: Not logged in. + content: + application/json: + schema: + properties: + error: + type: string + example: Not logged in. '403': description: User is not a Campaign Admin. content: @@ -1036,7 +1409,7 @@ paths: required: true schema: type: integer - format: int32 + format: int64 description: Deletes specified role. tags: - Role @@ -1050,6 +1423,15 @@ paths: message: type: string example: Successfully deleted role. + '401': + description: Not logged in. + content: + application/json: + schema: + properties: + error: + type: string + example: Not logged in. '403': description: User is not an admin of role's Campaign. content: @@ -1058,4 +1440,320 @@ paths: properties: error: type: string - example: Unauthorized \ No newline at end of file + example: Unauthorized + + /role/{id}/applications: + get: + operationId: getApplicationsByRoleID + parameters: + - name: id + in: path + description: Role ID + required: true + schema: + type: integer + format: int64 + description: Returns all applications to a specific role + tags: + - Role + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + applications: + type: array + items: + $ref: '#components/schemas/ApplicationDetails' + '401': + description: Not logged in. + content: + application/json: + schema: + properties: + error: + type: string + example: Not logged in. + '403': + description: User is not an Application Admin. + content: + application/json: + schema: + properties: + error: + type: string + example: Unauthorized + + /application/{id}: + get: + operationId: getApplicationByID + parameters: + - name: id + in: path + description: Application ID + required: true + schema: + type: integer + format: int64 + description: Returns an applications given its ID + tags: + - Application + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + application: + type: + $ref: '#components/schemas/ApplicationDetails' + '401': + description: Not logged in. + content: + application/json: + schema: + properties: + error: + type: string + example: Not logged in. + '403': + description: User is not an Application Admin. + content: + application/json: + schema: + properties: + error: + type: string + example: Unauthorized + + + /application/{id}/private: + put: + operationId: updateApplicationPrivateStatus + parameters: + - name: id + in: path + description: Application ID + required: true + schema: + type: integer + format: int64 + requestBody: + required: true + content: + application/json: + schema: + properties: + data: + type: + $ref: '#components/schemas/ApplicationStatus' + + description: Change Private Status of a specific Application + tags: + - Organisation + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + message: + type: string + example: Successfully updated Application Private Status. + '401': + description: Not logged in. + content: + application/json: + schema: + properties: + error: + type: string + example: Not logged in. + '403': + description: User is not an Application Admin. + content: + application/json: + schema: + properties: + error: + type: string + example: Unauthorized + + /application/{id}/status: + put: + operationId: updateApplicationStatus + parameters: + - name: id + in: path + description: Application ID + required: true + schema: + type: integer + format: int64 + requestBody: + required: true + content: + application/json: + schema: + properties: + data: + type: + $ref: '#components/schemas/ApplicationStatus' + + description: Change Status of a specific Application + tags: + - Organisation + responses: + '200': + description: OK + content: + application/json: + schema: + properties: + message: + type: string + example: Successfully updated Application Status. + '401': + description: Not logged in. + content: + application/json: + schema: + properties: + error: + type: string + example: Not logged in. + '403': + description: User is not an Application Admin. + content: + application/json: + schema: + properties: + error: + type: string + example: Unauthorized + +components: + schemas: + ApplicationStatus: + type: string + enum: + - Pending + - Rejected + - Successful + + OrganisationCampaign: + type: object + properties: + id: + type: integer + format: int64 + example: 6996987893965262849 + name: + type: string + example: 2024 Subcommittee Recruitment + cover_image: + type: string + example: 2d19617b-46fd-4927-9f53-77d69232ba5d + description: + type: string + example: Are you excited to make a difference? + starts_at: + type: string + example: 2024-03-15T18:25:43.511Z + ends_at: + type: string + example: 2024-04-15T18:25:43.511Z + + RoleDetails: + type: object + properties: + id: + type: integer + format: int64 + example: 7036987893965262849 + campaign_id: + type: integer + format: int64 + example: 1116987453965262849 + name: + type: string + example: Chief Mouser + description: + type: string + example: Larry the cat gone missing! now we need someone else to handle the rat issues at 10th Downing st. + min_available: + type: int32 + example: 1 + max_available: + type: int32 + example: 3 + finalised: + type: boolean + description: Whether this role has been finalised (e.g. max avaliable number) + example: False + + UserDetails: + type: object + properties: + id: + type: integer + format: int64 + example: 1541815603606036480 + email: + type: string + example: me@example.com + zid: + type: string + example: z5555555 + name: + type: string + example: Clancy Lion + pronouns: + type: string + example: They/Them + gender: + type: string + example: Male + degree_name: + type: string + example: Computer Science + degree_starting_year: + type: integer + example: 2024 + + ApplicationDetails: + type: object + properties: + id: + type: integer + format: int64 + example: 1541815603606036480 + campaign_id: + type: integer + format: int64 + example: 5141815603606036480 + user: + $ref: '#/components/schemas/UserDetails' + status: + $ref: '#/components/schemas/ApplicationStatus' + private_status: + $ref: '#/components/schemas/ApplicationStatus' + applied_roles: + type: array + items: + $ref: '#/components/schemas/ApplicationAppliedRoleDetails' + + ApplicationAppliedRoleDetails: + type: object + properties: + campaign_role_id: + type: integer + format: int64 + example: 1541815603606036480 + role_name: + type: String + example: UI/UX subcom \ No newline at end of file From 2ec5c18c11c94d1f6bde5297a024c9370b41860a Mon Sep 17 00:00:00 2001 From: Kavika Date: Fri, 29 Nov 2024 23:29:16 +1100 Subject: [PATCH 37/56] Email Templates and Offers (#528) * change all db pool in `Campaign` to transactions * move extracting user_id from request to helper function * add slugs to `Campaign` and `Organisation` * add endpoints to check slug availability * slug utility functions and checks * email templating and offer CRUD * fix email_template auth service join * offer CRUD * ran `cargo fmt` & remove unused imports --- .../20240406024211_create_organisations.sql | 1 + .../20240406025537_create_campaigns.sql | 4 +- .../20241124054711_email_templates.sql | 12 + backend/migrations/20241126113027_offers.sql | 32 ++ backend/server/Cargo.toml | 2 +- backend/server/src/handler/answer.rs | 10 +- backend/server/src/handler/campaign.rs | 80 ++++- backend/server/src/handler/email_template.rs | 42 +++ backend/server/src/handler/mod.rs | 2 + backend/server/src/handler/offer.rs | 66 ++++ backend/server/src/handler/organisation.rs | 72 +++- backend/server/src/handler/rating.rs | 3 +- backend/server/src/models/answer.rs | 10 +- backend/server/src/models/app.rs | 56 ++- backend/server/src/models/auth.rs | 323 +++++++----------- backend/server/src/models/campaign.rs | 96 +++++- backend/server/src/models/email_template.rs | 114 +++++++ backend/server/src/models/error.rs | 6 + backend/server/src/models/mod.rs | 2 + backend/server/src/models/offer.rs | 223 ++++++++++++ backend/server/src/models/organisation.rs | 104 +++++- backend/server/src/models/role.rs | 11 +- backend/server/src/service/auth.rs | 41 ++- backend/server/src/service/email_template.rs | 30 ++ backend/server/src/service/mod.rs | 2 + backend/server/src/service/offer.rs | 47 +++ 26 files changed, 1119 insertions(+), 272 deletions(-) create mode 100644 backend/migrations/20241124054711_email_templates.sql create mode 100644 backend/migrations/20241126113027_offers.sql create mode 100644 backend/server/src/handler/email_template.rs create mode 100644 backend/server/src/handler/offer.rs create mode 100644 backend/server/src/models/email_template.rs create mode 100644 backend/server/src/models/offer.rs create mode 100644 backend/server/src/service/email_template.rs create mode 100644 backend/server/src/service/offer.rs diff --git a/backend/migrations/20240406024211_create_organisations.sql b/backend/migrations/20240406024211_create_organisations.sql index ec67f1903..2c3bfdf79 100644 --- a/backend/migrations/20240406024211_create_organisations.sql +++ b/backend/migrations/20240406024211_create_organisations.sql @@ -1,5 +1,6 @@ CREATE TABLE organisations ( id BIGINT PRIMARY KEY, + slug TEXT NOT NULL UNIQUE, name TEXT NOT NULL UNIQUE, logo UUID, created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, diff --git a/backend/migrations/20240406025537_create_campaigns.sql b/backend/migrations/20240406025537_create_campaigns.sql index c300ee80f..b1d8b6ecb 100644 --- a/backend/migrations/20240406025537_create_campaigns.sql +++ b/backend/migrations/20240406025537_create_campaigns.sql @@ -1,6 +1,7 @@ CREATE TABLE campaigns ( id BIGINT PRIMARY KEY, organisation_id BIGINT NOT NULL, + slug TEXT NOT NULL, name TEXT NOT NULL, cover_image UUID, description TEXT, @@ -12,7 +13,8 @@ CREATE TABLE campaigns ( FOREIGN KEY(organisation_id) REFERENCES organisations(id) ON DELETE CASCADE - ON UPDATE CASCADE + ON UPDATE CASCADE, + UNIQUE (organisation_id, slug) ); CREATE TABLE campaign_roles ( diff --git a/backend/migrations/20241124054711_email_templates.sql b/backend/migrations/20241124054711_email_templates.sql new file mode 100644 index 000000000..393123c90 --- /dev/null +++ b/backend/migrations/20241124054711_email_templates.sql @@ -0,0 +1,12 @@ +CREATE TABLE email_templates ( + id BIGINT PRIMARY KEY, + organisation_id BIGINT NOT NULL, + name TEXT NOT NULL, + template TEXT NOT NULL, + CONSTRAINT FK_email_templates_organisations + FOREIGN KEY(organisation_id) + REFERENCES organisations(id) + ON DELETE CASCADE + ON UPDATE CASCADE, + UNIQUE (organisation_id, name) +); \ No newline at end of file diff --git a/backend/migrations/20241126113027_offers.sql b/backend/migrations/20241126113027_offers.sql new file mode 100644 index 000000000..afe639255 --- /dev/null +++ b/backend/migrations/20241126113027_offers.sql @@ -0,0 +1,32 @@ +CREATE TYPE offer_status AS ENUM ('Draft', 'Sent', 'Accepted', 'Declined'); + +CREATE TABLE offers ( + id BIGINT PRIMARY KEY, + campaign_id BIGINT NOT NULL, + application_id BIGINT NOT NULL, + email_template_id BIGINT NOT NULL, + role_id BIGINT NOT NULL, + expiry TIMESTAMPTZ NOT NULL, + status offer_status NOT NULL DEFAULT 'Draft', + created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, + CONSTRAINT FK_offers_campaigns + FOREIGN KEY(campaign_id) + REFERENCES campaigns(id) + ON DELETE CASCADE + ON UPDATE CASCADE, + CONSTRAINT FK_offers_applications + FOREIGN KEY(application_id) + REFERENCES applications(id) + ON DELETE CASCADE + ON UPDATE CASCADE, + CONSTRAINT FK_offers_email_templates + FOREIGN KEY(email_template_id) + REFERENCES email_templates(id) + ON DELETE CASCADE + ON UPDATE CASCADE, + CONSTRAINT FK_offers_roles + FOREIGN KEY(role_id) + REFERENCES campaign_roles(id) + ON DELETE CASCADE + ON UPDATE CASCADE +); \ No newline at end of file diff --git a/backend/server/Cargo.toml b/backend/server/Cargo.toml index 9c4babe2f..de3d9bb67 100644 --- a/backend/server/Cargo.toml +++ b/backend/server/Cargo.toml @@ -26,4 +26,4 @@ rust-s3 = "0.34.0" rs-snowflake = "0.6" jsonwebtoken = "9.1" dotenvy = "0.15" - +handlebars = "6.2" diff --git a/backend/server/src/handler/answer.rs b/backend/server/src/handler/answer.rs index 34f3e0ea6..065be1da9 100644 --- a/backend/server/src/handler/answer.rs +++ b/backend/server/src/handler/answer.rs @@ -1,6 +1,6 @@ use crate::models::answer::{Answer, NewAnswer}; use crate::models::app::AppState; -use crate::models::auth::{AnswerOwner, ApplicationOwner, AuthUser}; +use crate::models::auth::{AnswerOwner, ApplicationOwner}; use crate::models::error::ChaosError; use crate::models::transaction::DBTransaction; use axum::extract::{Json, Path, State}; @@ -13,14 +13,14 @@ pub struct AnswerHandler; impl AnswerHandler { pub async fn create( State(state): State, - Path(path): Path, - user: AuthUser, + Path(application_id): Path, + _user: ApplicationOwner, mut transaction: DBTransaction<'_>, Json(data): Json, ) -> Result { + // TODO: Check whether the question is contained in the campaign being applied to let id = Answer::create( - user.user_id, - data.application_id, + application_id, data.question_id, data.answer_data, state.snowflake_generator, diff --git a/backend/server/src/handler/campaign.rs b/backend/server/src/handler/campaign.rs index ed5b9e249..0e1db3934 100644 --- a/backend/server/src/handler/campaign.rs +++ b/backend/server/src/handler/campaign.rs @@ -6,6 +6,7 @@ use crate::models::auth::AuthUser; use crate::models::auth::CampaignAdmin; use crate::models::campaign::Campaign; use crate::models::error::ChaosError; +use crate::models::offer::Offer; use crate::models::role::{Role, RoleUpdate}; use crate::models::transaction::DBTransaction; use axum::extract::{Json, Path, State}; @@ -15,67 +16,87 @@ use axum::response::IntoResponse; pub struct CampaignHandler; impl CampaignHandler { pub async fn get( - State(state): State, + mut transaction: DBTransaction<'_>, Path(id): Path, _user: AuthUser, ) -> Result { - let campaign = Campaign::get(id, &state.db).await?; + let campaign = Campaign::get(id, &mut transaction.tx).await?; + transaction.tx.commit().await?; + Ok((StatusCode::OK, Json(campaign))) + } + + pub async fn get_by_slugs( + mut transaction: DBTransaction<'_>, + Path((organisation_slug, campaign_slug)): Path<(String, String)>, + _user: AuthUser, + ) -> Result { + let campaign = + Campaign::get_by_slugs(organisation_slug, campaign_slug, &mut transaction.tx).await?; + transaction.tx.commit().await?; Ok((StatusCode::OK, Json(campaign))) } pub async fn get_all( - State(state): State, + mut transaction: DBTransaction<'_>, _user: AuthUser, ) -> Result { - let campaigns = Campaign::get_all(&state.db).await?; + let campaigns = Campaign::get_all(&mut transaction.tx).await?; + transaction.tx.commit().await?; Ok((StatusCode::OK, Json(campaigns))) } pub async fn update( - State(state): State, + mut transaction: DBTransaction<'_>, Path(id): Path, _admin: CampaignAdmin, Json(request_body): Json, ) -> Result { - Campaign::update(id, request_body, &state.db).await?; + Campaign::update(id, request_body, &mut transaction.tx).await?; + transaction.tx.commit().await?; Ok((StatusCode::OK, "Successfully updated campaign")) } pub async fn update_banner( + mut transaction: DBTransaction<'_>, State(state): State, Path(id): Path, _admin: CampaignAdmin, ) -> Result { - let banner_url = Campaign::update_banner(id, &state.db, &state.storage_bucket).await?; + let banner_url = + Campaign::update_banner(id, &mut transaction.tx, &state.storage_bucket).await?; + transaction.tx.commit().await?; Ok((StatusCode::OK, Json(banner_url))) } pub async fn delete( - State(state): State, + mut transaction: DBTransaction<'_>, Path(id): Path, _admin: CampaignAdmin, ) -> Result { - Campaign::delete(id, &state.db).await?; + Campaign::delete(id, &mut transaction.tx).await?; + transaction.tx.commit().await?; Ok((StatusCode::OK, "Successfully deleted campaign")) } pub async fn create_role( + mut transaction: DBTransaction<'_>, State(state): State, Path(id): Path, _admin: CampaignAdmin, Json(data): Json, ) -> Result { - Role::create(id, data, &state.db, state.snowflake_generator).await?; + Role::create(id, data, &mut transaction.tx, state.snowflake_generator).await?; + transaction.tx.commit().await?; Ok((StatusCode::OK, "Successfully created role")) } pub async fn get_roles( - State(state): State, + mut transaction: DBTransaction<'_>, Path(id): Path, _user: AuthUser, ) -> Result { - let roles = Role::get_all_in_campaign(id, &state.db).await?; - + let roles = Role::get_all_in_campaign(id, &mut transaction.tx).await?; + transaction.tx.commit().await?; Ok((StatusCode::OK, Json(roles))) } @@ -107,4 +128,37 @@ impl CampaignHandler { transaction.tx.commit().await?; Ok((StatusCode::OK, Json(applications))) } + + pub async fn create_offer( + Path(id): Path, + State(state): State, + _admin: CampaignAdmin, + mut transaction: DBTransaction<'_>, + Json(data): Json, + ) -> Result { + let _ = Offer::create( + id, + data.application_id, + data.email_template_id, + data.role_id, + data.expiry, + &mut transaction.tx, + state.snowflake_generator, + ) + .await?; + transaction.tx.commit().await?; + + Ok((StatusCode::OK, "Successfully created offer")) + } + + pub async fn get_offers( + mut transaction: DBTransaction<'_>, + Path(id): Path, + _user: CampaignAdmin, + ) -> Result { + let offers = Offer::get_by_campaign(id, &mut transaction.tx).await?; + transaction.tx.commit().await?; + + Ok((StatusCode::OK, Json(offers))) + } } diff --git a/backend/server/src/handler/email_template.rs b/backend/server/src/handler/email_template.rs new file mode 100644 index 000000000..e392834f1 --- /dev/null +++ b/backend/server/src/handler/email_template.rs @@ -0,0 +1,42 @@ +use crate::models::app::AppState; +use crate::models::auth::EmailTemplateAdmin; +use crate::models::email_template::EmailTemplate; +use crate::models::error::ChaosError; +use crate::models::transaction::DBTransaction; +use axum::extract::{Json, Path, State}; +use axum::http::StatusCode; +use axum::response::IntoResponse; + +pub struct EmailTemplateHandler; +impl EmailTemplateHandler { + pub async fn get( + mut transaction: DBTransaction<'_>, + Path(id): Path, + _user: EmailTemplateAdmin, + ) -> Result { + let email_template = EmailTemplate::get(id, &mut transaction.tx).await?; + + Ok((StatusCode::OK, Json(email_template))) + } + + pub async fn update( + _user: EmailTemplateAdmin, + Path(id): Path, + State(state): State, + Json(request_body): Json, + ) -> Result { + EmailTemplate::update(id, request_body.name, request_body.template, &state.db).await?; + + Ok((StatusCode::OK, "Successfully updated email template")) + } + + pub async fn delete( + _user: EmailTemplateAdmin, + Path(id): Path, + State(state): State, + ) -> Result { + EmailTemplate::delete(id, &state.db).await?; + + Ok((StatusCode::OK, "Successfully delete email template")) + } +} diff --git a/backend/server/src/handler/mod.rs b/backend/server/src/handler/mod.rs index 73a946273..336754275 100644 --- a/backend/server/src/handler/mod.rs +++ b/backend/server/src/handler/mod.rs @@ -2,6 +2,8 @@ pub mod answer; pub mod application; pub mod auth; pub mod campaign; +pub mod email_template; +pub mod offer; pub mod organisation; pub mod question; pub mod rating; diff --git a/backend/server/src/handler/offer.rs b/backend/server/src/handler/offer.rs new file mode 100644 index 000000000..92297c633 --- /dev/null +++ b/backend/server/src/handler/offer.rs @@ -0,0 +1,66 @@ +use crate::models::auth::{OfferAdmin, OfferRecipient}; +use crate::models::error::ChaosError; +use crate::models::offer::{Offer, OfferReply}; +use crate::models::transaction::DBTransaction; +use axum::extract::{Json, Path}; +use axum::http::StatusCode; +use axum::response::IntoResponse; + +pub struct OfferHandler; +impl OfferHandler { + pub async fn get( + mut transaction: DBTransaction<'_>, + Path(id): Path, + _user: OfferAdmin, + ) -> Result { + let offer = Offer::get(id, &mut transaction.tx).await?; + transaction.tx.commit().await?; + + Ok((StatusCode::OK, Json(offer))) + } + + pub async fn delete( + mut transaction: DBTransaction<'_>, + Path(id): Path, + _user: OfferAdmin, + ) -> Result { + Offer::delete(id, &mut transaction.tx).await?; + transaction.tx.commit().await?; + + Ok((StatusCode::OK, "Successfully deleted offer")) + } + + pub async fn reply( + mut transaction: DBTransaction<'_>, + Path(id): Path, + _user: OfferRecipient, + Json(reply): Json, + ) -> Result { + Offer::reply(id, reply.accept, &mut transaction.tx).await?; + transaction.tx.commit().await?; + + Ok((StatusCode::OK, "Successfully accepted offer")) + } + + pub async fn preview_email( + mut transaction: DBTransaction<'_>, + Path(id): Path, + _user: OfferAdmin, + ) -> Result { + let string = Offer::preview_email(id, &mut transaction.tx).await?; + transaction.tx.commit().await?; + + Ok((StatusCode::OK, string)) + } + + pub async fn send_offer( + mut transaction: DBTransaction<'_>, + Path(id): Path, + _user: OfferAdmin, + ) -> Result { + Offer::send_offer(id, &mut transaction.tx).await?; + transaction.tx.commit().await?; + + Ok((StatusCode::OK, "Successfully sent offer")) + } +} diff --git a/backend/server/src/handler/organisation.rs b/backend/server/src/handler/organisation.rs index f98b27b23..7950f1fb3 100644 --- a/backend/server/src/handler/organisation.rs +++ b/backend/server/src/handler/organisation.rs @@ -2,8 +2,12 @@ use crate::models; use crate::models::app::AppState; use crate::models::auth::SuperUser; use crate::models::auth::{AuthUser, OrganisationAdmin}; +use crate::models::campaign::Campaign; +use crate::models::email_template::EmailTemplate; use crate::models::error::ChaosError; -use crate::models::organisation::{AdminToRemove, AdminUpdateList, NewOrganisation, Organisation}; +use crate::models::organisation::{ + AdminToRemove, AdminUpdateList, NewOrganisation, Organisation, SlugCheck, +}; use crate::models::transaction::DBTransaction; use axum::extract::{Json, Path, State}; use axum::http::StatusCode; @@ -20,6 +24,7 @@ impl OrganisationHandler { ) -> Result { Organisation::create( data.admin, + data.slug, data.name, state.snowflake_generator, &mut transaction.tx, @@ -30,6 +35,16 @@ impl OrganisationHandler { Ok((StatusCode::OK, "Successfully created organisation")) } + pub async fn check_organisation_slug_availability( + State(state): State, + _user: SuperUser, + Json(data): Json, + ) -> Result { + Organisation::check_slug_availability(data.slug, &state.db).await?; + + Ok((StatusCode::OK, "Organisation slug is available")) + } + pub async fn get( State(state): State, Path(id): Path, @@ -39,6 +54,15 @@ impl OrganisationHandler { Ok((StatusCode::OK, Json(org))) } + pub async fn get_by_slug( + State(state): State, + Path(slug): Path, + _user: AuthUser, + ) -> Result { + let org = Organisation::get_by_slug(slug, &state.db).await?; + Ok((StatusCode::OK, Json(org))) + } + pub async fn delete( State(state): State, Path(id): Path, @@ -141,21 +165,61 @@ impl OrganisationHandler { pub async fn create_campaign( Path(id): Path, - State(mut state): State, + State(state): State, _admin: OrganisationAdmin, - Json(request_body): Json, + Json(request_body): Json, ) -> Result { Organisation::create_campaign( id, + request_body.slug, request_body.name, request_body.description, request_body.starts_at, request_body.ends_at, &state.db, - &mut state.snowflake_generator, + state.snowflake_generator, ) .await?; Ok((StatusCode::OK, "Successfully created campaign")) } + + pub async fn check_campaign_slug_availability( + Path(organisation_id): Path, + State(state): State, + _user: OrganisationAdmin, + Json(data): Json, + ) -> Result { + Campaign::check_slug_availability(organisation_id, data.slug, &state.db).await?; + + Ok((StatusCode::OK, "Campaign slug is available")) + } + + pub async fn create_email_template( + Path(id): Path, + State(state): State, + _admin: OrganisationAdmin, + Json(request_body): Json, + ) -> Result { + Organisation::create_email_template( + id, + request_body.name, + request_body.template, + &state.db, + state.snowflake_generator, + ) + .await?; + + Ok((StatusCode::OK, "Successfully created email template")) + } + + pub async fn get_all_email_templates( + _user: OrganisationAdmin, + Path(id): Path, + State(state): State, + ) -> Result { + let email_templates = EmailTemplate::get_all_by_organisation(id, &state.db).await?; + + Ok((StatusCode::OK, Json(email_templates))) + } } diff --git a/backend/server/src/handler/rating.rs b/backend/server/src/handler/rating.rs index 2ec36960a..5c93e2034 100644 --- a/backend/server/src/handler/rating.rs +++ b/backend/server/src/handler/rating.rs @@ -1,7 +1,6 @@ use crate::models::app::AppState; use crate::models::auth::{ - ApplicationCreatorGivenApplicationId, ApplicationReviewerGivenApplicationId, - ApplicationReviewerGivenRatingId, RatingCreator, + ApplicationReviewerGivenApplicationId, ApplicationReviewerGivenRatingId, RatingCreator, }; use crate::models::error::ChaosError; use crate::models::rating::{NewRating, Rating}; diff --git a/backend/server/src/models/answer.rs b/backend/server/src/models/answer.rs index 670a7ba81..c9f517725 100644 --- a/backend/server/src/models/answer.rs +++ b/backend/server/src/models/answer.rs @@ -1,11 +1,9 @@ use crate::models::error::ChaosError; -use crate::models::question::{ - MultiOptionData, MultiOptionQuestionOption, QuestionData, QuestionType, QuestionTypeParent, -}; +use crate::models::question::QuestionType; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use snowflake::SnowflakeIdGenerator; -use sqlx::{Pool, Postgres, Transaction}; +use sqlx::{Postgres, Transaction}; use std::ops::DerefMut; /// The `Answer` type that will be sent in API responses. @@ -64,7 +62,6 @@ pub struct AnswerTypeApplicationId { impl Answer { pub async fn create( - user_id: i64, application_id: i64, question_id: i64, answer_data: AnswerData, @@ -379,9 +376,6 @@ impl AnswerData { let options = ranking_answers.expect("Data should exist for Ranking variant"); AnswerData::Ranking(options) } - _ => { - AnswerData::ShortAnswer("".to_string()) // Should never be reached, hence return ShortAnswer - } }; } diff --git a/backend/server/src/models/app.rs b/backend/server/src/models/app.rs index ed41b78fb..5fd59143f 100644 --- a/backend/server/src/models/app.rs +++ b/backend/server/src/models/app.rs @@ -2,6 +2,8 @@ use crate::handler::answer::AnswerHandler; use crate::handler::application::ApplicationHandler; use crate::handler::auth::google_callback; use crate::handler::campaign::CampaignHandler; +use crate::handler::email_template::EmailTemplateHandler; +use crate::handler::offer::OfferHandler; use crate::handler::organisation::OrganisationHandler; use crate::handler::question::QuestionHandler; use crate::handler::rating::RatingHandler; @@ -89,18 +91,38 @@ pub async fn app() -> Result { get(ApplicationHandler::get_from_curr_user), ) .route("/api/v1/organisation", post(OrganisationHandler::create)) + .route( + "/api/v1/organisation/slug_check", + post(OrganisationHandler::check_organisation_slug_availability), + ) .route( "/api/v1/organisation/:organisation_id", get(OrganisationHandler::get).delete(OrganisationHandler::delete), ) + .route( + "/api/v1/organisation/slug/:slug", + get(OrganisationHandler::get_by_slug), + ) .route( "/api/v1/organisation/:organisation_id/campaign", post(OrganisationHandler::create_campaign), ) + .route( + "/api/v1/organisation/:organisation_id/campaign/slug_check", + post(OrganisationHandler::check_campaign_slug_availability), + ) .route( "/api/v1/organisation/:organisation_id/campaigns", get(OrganisationHandler::get_campaigns), ) + .route( + "/api/v1/organisation/:organisation_id/email_template", + post(OrganisationHandler::create_email_template), + ) + .route( + "/api/v1/organisation/:organisation_id/email_templates", + get(OrganisationHandler::get_all_email_templates), + ) .route( "/api/v1/organisation/:organisation_id/logo", patch(OrganisationHandler::update_logo), @@ -163,6 +185,10 @@ pub async fn app() -> Result { .put(CampaignHandler::update) .delete(CampaignHandler::delete), ) + .route( + "/api/v1/campaign/slug/:organisation_slug/:campaign_slug", + get(CampaignHandler::get_by_slugs), + ) .route("/api/v1/campaign", get(CampaignHandler::get_all)) .route( "/api/v1/campaign/:campaign_id/question", @@ -184,6 +210,14 @@ pub async fn app() -> Result { "/api/v1/campaign/:campaign_id/application", post(CampaignHandler::create_application), ) + .route( + "/api/v1/campaign/:campaign_id/offer", + post(CampaignHandler::create_offer), + ) + .route( + "/api/v1/campaign/:campaign_id/offers", + get(CampaignHandler::get_offers), + ) .route( "/api/v1/application/:application_id", get(ApplicationHandler::get), @@ -201,7 +235,7 @@ pub async fn app() -> Result { get(AnswerHandler::get_all_common_by_application), ) .route( - "/api/v1/application/:applicaiton_id/answer", + "/api/v1/application/:application_id/answer", post(AnswerHandler::create), ) .route( @@ -212,5 +246,25 @@ pub async fn app() -> Result { "/api/v1/answer/:answer_id", patch(AnswerHandler::update).delete(AnswerHandler::delete), ) + .route( + "/api/v1/email_template/:template_id", + get(EmailTemplateHandler::get) + .patch(EmailTemplateHandler::update) + .delete(EmailTemplateHandler::delete), + ) + .route( + "/api/v1/offer/:offer_id", + get(OfferHandler::get) + .delete(OfferHandler::delete) + .post(OfferHandler::reply), + ) + .route( + "/api/v1/offer/:offer_id/preview", + get(OfferHandler::preview_email), + ) + .route( + "/api/v1/offer/:offer_id/send", + post(OfferHandler::send_offer), + ) .with_state(state)) } diff --git a/backend/server/src/models/auth.rs b/backend/server/src/models/auth.rs index f28ac9f0c..38902d2b9 100644 --- a/backend/server/src/models/auth.rs +++ b/backend/server/src/models/auth.rs @@ -2,9 +2,10 @@ use crate::models::app::AppState; use crate::models::error::ChaosError; use crate::service::answer::user_is_answer_owner; use crate::service::application::{user_is_application_admin, user_is_application_owner}; -use crate::service::auth::is_super_user; +use crate::service::auth::{assert_is_super_user, extract_user_id_from_request}; use crate::service::campaign::user_is_campaign_admin; -use crate::service::jwt::decode_auth_token; +use crate::service::email_template::user_is_email_template_admin; +use crate::service::offer::{assert_user_is_offer_admin, assert_user_is_offer_recipient}; use crate::service::organisation::assert_user_is_organisation_admin; use crate::service::question::user_is_question_admin; use crate::service::rating::{ @@ -16,7 +17,6 @@ use axum::extract::{FromRef, FromRequestParts, Path}; use axum::http::request::Parts; use axum::response::{IntoResponse, Redirect, Response}; use axum::{async_trait, RequestPartsExt}; -use axum_extra::{headers::Cookie, TypedHeader}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; @@ -58,21 +58,9 @@ where async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { let app_state = AppState::from_ref(state); - let decoding_key = &app_state.decoding_key; - let jwt_validator = &app_state.jwt_validator; - let TypedHeader(cookies) = parts - .extract::>() - .await - .map_err(|_| ChaosError::NotLoggedIn)?; - - let token = cookies.get("auth_token").ok_or(ChaosError::NotLoggedIn)?; + let user_id = extract_user_id_from_request(parts, &app_state).await?; - let claims = - decode_auth_token(token, decoding_key, jwt_validator).ok_or(ChaosError::NotLoggedIn)?; - - Ok(AuthUser { - user_id: claims.sub, - }) + Ok(AuthUser { user_id }) } } @@ -91,30 +79,11 @@ where async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { let app_state = AppState::from_ref(state); - let decoding_key = &app_state.decoding_key; - let jwt_validator = &app_state.jwt_validator; - let TypedHeader(cookies) = parts - .extract::>() - .await - .map_err(|_| ChaosError::NotLoggedIn)?; + let user_id = extract_user_id_from_request(parts, &app_state).await?; - let token = cookies.get("auth_token").ok_or(ChaosError::NotLoggedIn)?; + assert_is_super_user(user_id, &app_state.db).await?; - let claims = - decode_auth_token(token, decoding_key, jwt_validator).ok_or(ChaosError::NotLoggedIn)?; - - let pool = &app_state.db; - let possible_user = is_super_user(claims.sub, pool).await; - - if let Ok(is_auth_user) = possible_user { - if is_auth_user { - return Ok(SuperUser { - user_id: claims.sub, - }); - } - } - - Err(ChaosError::Unauthorized) + Ok(SuperUser { user_id }) } } @@ -132,20 +101,7 @@ where async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { let app_state = AppState::from_ref(state); - let decoding_key = &app_state.decoding_key; - let jwt_validator = &app_state.jwt_validator; - let TypedHeader(cookies) = parts - .extract::>() - .await - .map_err(|_| ChaosError::NotLoggedIn)?; - - let token = cookies.get("auth_token").ok_or(ChaosError::NotLoggedIn)?; - - let claims = - decode_auth_token(token, decoding_key, jwt_validator).ok_or(ChaosError::NotLoggedIn)?; - - let pool = &app_state.db; - let user_id = claims.sub; + let user_id = extract_user_id_from_request(parts, &app_state).await?; let organisation_id = *parts .extract::>>() @@ -154,7 +110,7 @@ where .get("organisation_id") .ok_or(ChaosError::BadRequest)?; - assert_user_is_organisation_admin(user_id, organisation_id, pool).await?; + assert_user_is_organisation_admin(user_id, organisation_id, &app_state.db).await?; Ok(OrganisationAdmin { user_id }) } @@ -174,20 +130,7 @@ where async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { let app_state = AppState::from_ref(state); - let decoding_key = &app_state.decoding_key; - let jwt_validator = &app_state.jwt_validator; - let TypedHeader(cookies) = parts - .extract::>() - .await - .map_err(|_| ChaosError::NotLoggedIn)?; - - let token = cookies.get("auth_token").ok_or(ChaosError::NotLoggedIn)?; - - let claims = - decode_auth_token(token, decoding_key, jwt_validator).ok_or(ChaosError::NotLoggedIn)?; - - let pool = &app_state.db; - let user_id = claims.sub; + let user_id = extract_user_id_from_request(parts, &app_state).await?; let campaign_id = *parts .extract::>>() @@ -196,7 +139,7 @@ where .get("campaign_id") .ok_or(ChaosError::BadRequest)?; - user_is_campaign_admin(user_id, campaign_id, pool).await?; + user_is_campaign_admin(user_id, campaign_id, &app_state.db).await?; Ok(CampaignAdmin { user_id }) } @@ -216,20 +159,7 @@ where async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { let app_state = AppState::from_ref(state); - let decoding_key = &app_state.decoding_key; - let jwt_validator = &app_state.jwt_validator; - let TypedHeader(cookies) = parts - .extract::>() - .await - .map_err(|_| ChaosError::NotLoggedIn)?; - - let token = cookies.get("auth_token").ok_or(ChaosError::NotLoggedIn)?; - - let claims = - decode_auth_token(token, decoding_key, jwt_validator).ok_or(ChaosError::NotLoggedIn)?; - - let pool = &app_state.db; - let user_id = claims.sub; + let user_id = extract_user_id_from_request(parts, &app_state).await?; let role_id = *parts .extract::>>() @@ -238,7 +168,7 @@ where .get("role_id") .ok_or(ChaosError::BadRequest)?; - user_is_role_admin(user_id, role_id, pool).await?; + user_is_role_admin(user_id, role_id, &app_state.db).await?; Ok(RoleAdmin { user_id }) } @@ -258,27 +188,14 @@ where async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { let app_state = AppState::from_ref(state); - let decoding_key = &app_state.decoding_key; - let jwt_validator = &app_state.jwt_validator; - let TypedHeader(cookies) = parts - .extract::>() - .await - .map_err(|_| ChaosError::NotLoggedIn)?; - - let token = cookies.get("auth_token").ok_or(ChaosError::NotLoggedIn)?; - - let claims = - decode_auth_token(token, decoding_key, jwt_validator).ok_or(ChaosError::NotLoggedIn)?; - - let pool = &app_state.db; - let user_id = claims.sub; + let user_id = extract_user_id_from_request(parts, &app_state).await?; let Path(application_id) = parts .extract::>() .await .map_err(|_| ChaosError::BadRequest)?; - user_is_application_admin(user_id, application_id, pool).await?; + user_is_application_admin(user_id, application_id, &app_state.db).await?; Ok(ApplicationAdmin { user_id }) } @@ -305,29 +222,15 @@ where type Rejection = ChaosError; async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { - // TODO: put into separate function, since this is just getting the id through jwt, and duplicated here. let app_state = AppState::from_ref(state); - let decoding_key = &app_state.decoding_key; - let jwt_validator = &app_state.jwt_validator; - let TypedHeader(cookies) = parts - .extract::>() - .await - .map_err(|_| ChaosError::NotLoggedIn)?; - - let token = cookies.get("auth_token").ok_or(ChaosError::NotLoggedIn)?; - - let claims = - decode_auth_token(token, decoding_key, jwt_validator).ok_or(ChaosError::NotLoggedIn)?; - - let pool = &app_state.db; - let user_id = claims.sub; + let user_id = extract_user_id_from_request(parts, &app_state).await?; let Path(application_id) = parts .extract::>() .await .map_err(|_| ChaosError::BadRequest)?; - assert_user_is_organisation_member(user_id, application_id, pool).await?; + assert_user_is_organisation_member(user_id, application_id, &app_state.db).await?; Ok(ApplicationReviewerGivenApplicationId { user_id }) } @@ -347,29 +250,15 @@ where type Rejection = ChaosError; async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { - // TODO: put into separate function, since this is just getting the id through jwt, and duplicated here. let app_state = AppState::from_ref(state); - let decoding_key = &app_state.decoding_key; - let jwt_validator = &app_state.jwt_validator; - let TypedHeader(cookies) = parts - .extract::>() - .await - .map_err(|_| ChaosError::NotLoggedIn)?; - - let token = cookies.get("auth_token").ok_or(ChaosError::NotLoggedIn)?; - - let claims = - decode_auth_token(token, decoding_key, jwt_validator).ok_or(ChaosError::NotLoggedIn)?; - - let pool = &app_state.db; - let user_id = claims.sub; + let user_id = extract_user_id_from_request(parts, &app_state).await?; let Path(application_id) = parts .extract::>() .await .map_err(|_| ChaosError::BadRequest)?; - assert_user_is_organisation_member(user_id, application_id, pool).await?; + assert_user_is_organisation_member(user_id, application_id, &app_state.db).await?; Ok(ApplicationCreatorGivenApplicationId { user_id }) } @@ -389,29 +278,16 @@ where type Rejection = ChaosError; async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { - // TODO: put into separate function, since this is just getting the id through jwt, and duplicated here. let app_state = AppState::from_ref(state); - let decoding_key = &app_state.decoding_key; - let jwt_validator = &app_state.jwt_validator; - let TypedHeader(cookies) = parts - .extract::>() - .await - .map_err(|_| ChaosError::NotLoggedIn)?; - - let token = cookies.get("auth_token").ok_or(ChaosError::NotLoggedIn)?; - - let claims = - decode_auth_token(token, decoding_key, jwt_validator).ok_or(ChaosError::NotLoggedIn)?; - - let pool = &app_state.db; - let user_id = claims.sub; + let user_id = extract_user_id_from_request(parts, &app_state).await?; let Path(rating_id) = parts .extract::>() .await .map_err(|_| ChaosError::BadRequest)?; - assert_user_is_application_reviewer_given_rating_id(user_id, rating_id, pool).await?; + assert_user_is_application_reviewer_given_rating_id(user_id, rating_id, &app_state.db) + .await?; Ok(ApplicationReviewerGivenRatingId { user_id }) } @@ -430,29 +306,16 @@ where type Rejection = ChaosError; async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { - // TODO: put into separate function, since this is just getting the id through jwt, and duplicated here. let app_state = AppState::from_ref(state); - let decoding_key = &app_state.decoding_key; - let jwt_validator = &app_state.jwt_validator; - let TypedHeader(cookies) = parts - .extract::>() - .await - .map_err(|_| ChaosError::NotLoggedIn)?; - - let token = cookies.get("auth_token").ok_or(ChaosError::NotLoggedIn)?; - - let claims = - decode_auth_token(token, decoding_key, jwt_validator).ok_or(ChaosError::NotLoggedIn)?; - - let pool = &app_state.db; - let user_id = claims.sub; + let user_id = extract_user_id_from_request(parts, &app_state).await?; let Path(rating_id) = parts .extract::>() .await .map_err(|_| ChaosError::BadRequest)?; - assert_user_is_rating_creator_and_organisation_member(user_id, rating_id, pool).await?; + assert_user_is_rating_creator_and_organisation_member(user_id, rating_id, &app_state.db) + .await?; Ok(RatingCreator { user_id }) } @@ -472,20 +335,7 @@ where async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { let app_state = AppState::from_ref(state); - let decoding_key = &app_state.decoding_key; - let jwt_validator = &app_state.jwt_validator; - let TypedHeader(cookies) = parts - .extract::>() - .await - .map_err(|_| ChaosError::NotLoggedIn)?; - - let token = cookies.get("auth_token").ok_or(ChaosError::NotLoggedIn)?; - - let claims = - decode_auth_token(token, decoding_key, jwt_validator).ok_or(ChaosError::NotLoggedIn)?; - - let pool = &app_state.db; - let user_id = claims.sub; + let user_id = extract_user_id_from_request(parts, &app_state).await?; let question_id = *parts .extract::>>() @@ -494,7 +344,7 @@ where .get("question_id") .ok_or(ChaosError::BadRequest)?; - user_is_question_admin(user_id, question_id, pool).await?; + user_is_question_admin(user_id, question_id, &app_state.db).await?; Ok(QuestionAdmin { user_id }) } @@ -514,20 +364,36 @@ where async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { let app_state = AppState::from_ref(state); - let decoding_key = &app_state.decoding_key; - let jwt_validator = &app_state.jwt_validator; - let TypedHeader(cookies) = parts - .extract::>() + let user_id = extract_user_id_from_request(parts, &app_state).await?; + + let application_id = *parts + .extract::>>() .await - .map_err(|_| ChaosError::NotLoggedIn)?; + .map_err(|_| ChaosError::BadRequest)? + .get("application_id") + .ok_or(ChaosError::BadRequest)?; - let token = cookies.get("auth_token").ok_or(ChaosError::NotLoggedIn)?; + user_is_application_owner(user_id, application_id, &app_state.db).await?; - let claims = - decode_auth_token(token, decoding_key, jwt_validator).ok_or(ChaosError::NotLoggedIn)?; + Ok(ApplicationOwner { user_id }) + } +} - let pool = &app_state.db; - let user_id = claims.sub; +pub struct AnswerOwner { + pub user_id: i64, +} + +#[async_trait] +impl FromRequestParts for AnswerOwner +where + AppState: FromRef, + S: Send + Sync, +{ + type Rejection = ChaosError; + + async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { + let app_state = AppState::from_ref(state); + let user_id = extract_user_id_from_request(parts, &app_state).await?; let application_id = *parts .extract::>>() @@ -536,18 +402,18 @@ where .get("application_id") .ok_or(ChaosError::BadRequest)?; - user_is_application_owner(user_id, application_id, pool).await?; + user_is_answer_owner(user_id, application_id, &app_state.db).await?; - Ok(ApplicationOwner { user_id }) + Ok(AnswerOwner { user_id }) } } -pub struct AnswerOwner { +pub struct EmailTemplateAdmin { pub user_id: i64, } #[async_trait] -impl FromRequestParts for AnswerOwner +impl FromRequestParts for EmailTemplateAdmin where AppState: FromRef, S: Send + Sync, @@ -556,30 +422,75 @@ where async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { let app_state = AppState::from_ref(state); - let decoding_key = &app_state.decoding_key; - let jwt_validator = &app_state.jwt_validator; - let TypedHeader(cookies) = parts - .extract::>() + let user_id = extract_user_id_from_request(parts, &app_state).await?; + + let template_id = *parts + .extract::>>() .await - .map_err(|_| ChaosError::NotLoggedIn)?; + .map_err(|_| ChaosError::BadRequest)? + .get("template_id") + .ok_or(ChaosError::BadRequest)?; - let token = cookies.get("auth_token").ok_or(ChaosError::NotLoggedIn)?; + user_is_email_template_admin(user_id, template_id, &app_state.db).await?; - let claims = - decode_auth_token(token, decoding_key, jwt_validator).ok_or(ChaosError::NotLoggedIn)?; + Ok(EmailTemplateAdmin { user_id }) + } +} - let pool = &app_state.db; - let user_id = claims.sub; +pub struct OfferAdmin { + pub user_id: i64, +} - let application_id = *parts +#[async_trait] +impl FromRequestParts for OfferAdmin +where + AppState: FromRef, + S: Send + Sync, +{ + type Rejection = ChaosError; + + async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { + let app_state = AppState::from_ref(state); + let user_id = extract_user_id_from_request(parts, &app_state).await?; + + let offer_id = *parts .extract::>>() .await .map_err(|_| ChaosError::BadRequest)? - .get("application_id") + .get("offer_id") .ok_or(ChaosError::BadRequest)?; - user_is_answer_owner(user_id, application_id, pool).await?; + assert_user_is_offer_admin(user_id, offer_id, &app_state.db).await?; - Ok(AnswerOwner { user_id }) + Ok(OfferAdmin { user_id }) + } +} + +pub struct OfferRecipient { + pub user_id: i64, +} + +#[async_trait] +impl FromRequestParts for OfferRecipient +where + AppState: FromRef, + S: Send + Sync, +{ + type Rejection = ChaosError; + + async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { + let app_state = AppState::from_ref(state); + let user_id = extract_user_id_from_request(parts, &app_state).await?; + + let offer_id = *parts + .extract::>>() + .await + .map_err(|_| ChaosError::BadRequest)? + .get("offer_id") + .ok_or(ChaosError::BadRequest)?; + + assert_user_is_offer_recipient(user_id, offer_id, &app_state.db).await?; + + Ok(OfferRecipient { user_id }) } } diff --git a/backend/server/src/models/campaign.rs b/backend/server/src/models/campaign.rs index eb750de71..5897dc27f 100644 --- a/backend/server/src/models/campaign.rs +++ b/backend/server/src/models/campaign.rs @@ -1,8 +1,9 @@ use chrono::{DateTime, Utc}; use s3::Bucket; use serde::{Deserialize, Serialize}; -use sqlx::FromRow; +use sqlx::{FromRow, Transaction}; use sqlx::{Pool, Postgres}; +use std::ops::DerefMut; use uuid::Uuid; use super::{error::ChaosError, storage::Storage}; @@ -10,6 +11,7 @@ use super::{error::ChaosError, storage::Storage}; #[derive(Deserialize, Serialize, Clone, FromRow, Debug)] pub struct Campaign { pub id: i64, + pub slug: String, pub name: String, pub organisation_id: i64, pub organisation_name: String, @@ -24,8 +26,10 @@ pub struct Campaign { #[derive(Deserialize, Serialize, Clone, FromRow, Debug)] pub struct CampaignDetails { pub id: i64, + pub campaign_slug: String, pub name: String, pub organisation_id: i64, + pub organisation_slug: String, pub organisation_name: String, pub cover_image: Option, pub description: Option, @@ -35,6 +39,7 @@ pub struct CampaignDetails { #[derive(Deserialize, Serialize, Clone, FromRow, Debug)] pub struct OrganisationCampaign { pub id: i64, + pub slug: String, pub name: String, pub cover_image: Option, pub description: Option, @@ -44,6 +49,7 @@ pub struct OrganisationCampaign { #[derive(Deserialize, Serialize, Clone, FromRow, Debug)] pub struct CampaignUpdate { + pub slug: String, pub name: String, pub description: String, pub starts_at: DateTime, @@ -57,7 +63,9 @@ pub struct CampaignBannerUpdate { impl Campaign { /// Get a list of all campaigns, both published and unpublished - pub async fn get_all(pool: &Pool) -> Result, ChaosError> { + pub async fn get_all( + transaction: &mut Transaction<'_, Postgres>, + ) -> Result, ChaosError> { let campaigns = sqlx::query_as!( Campaign, " @@ -65,26 +73,82 @@ impl Campaign { JOIN organisations o on c.organisation_id = o.id " ) - .fetch_all(pool) + .fetch_all(transaction.deref_mut()) .await?; Ok(campaigns) } /// Get a campaign based on it's id - pub async fn get(id: i64, pool: &Pool) -> Result { + pub async fn get( + id: i64, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result { let campaign = sqlx::query_as!( CampaignDetails, " - SELECT c.id, c.name, c.organisation_id, o.name as organisation_name, - c.cover_image, c.description, c.starts_at, c.ends_at + SELECT c.id, c.slug AS campaign_slug, c.name, c.organisation_id, + o.slug AS organisation_slug, o.name as organisation_name, c.cover_image, + c.description, c.starts_at, c.ends_at FROM campaigns c JOIN organisations o on c.organisation_id = o.id WHERE c.id = $1 ", id ) + .fetch_one(transaction.deref_mut()) + .await?; + + Ok(campaign) + } + + pub async fn check_slug_availability( + organisation_id: i64, + slug: String, + pool: &Pool, + ) -> Result<(), ChaosError> { + if !slug.is_ascii() { + return Err(ChaosError::BadRequest); + } + + let exists = sqlx::query!( + " + SELECT EXISTS(SELECT 1 FROM campaigns WHERE organisation_id = $1 AND slug = $2) + ", + organisation_id, + slug + ) .fetch_one(pool) + .await? + .exists + .expect("`exists` should always exist in this query result"); + + if exists { + return Err(ChaosError::BadRequest); + } + + Ok(()) + } + + pub async fn get_by_slugs( + organisation_slug: String, + campaign_slug: String, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result { + let campaign = sqlx::query_as!( + CampaignDetails, + " + SELECT c.id, c.slug AS campaign_slug, c.name, c.organisation_id, + o.slug AS organisation_slug, o.name as organisation_name, c.cover_image, + c.description, c.starts_at, c.ends_at + FROM campaigns c + JOIN organisations o on c.organisation_id = o.id + WHERE c.slug = $1 AND o.slug = $2 + ", + campaign_slug, + organisation_slug + ) + .fetch_one(transaction.deref_mut()) .await?; Ok(campaign) @@ -94,21 +158,22 @@ impl Campaign { pub async fn update( id: i64, update: CampaignUpdate, - pool: &Pool, + transaction: &mut Transaction<'_, Postgres>, ) -> Result<(), ChaosError> { _ = sqlx::query!( " UPDATE campaigns - SET name = $1, description = $2, starts_at = $3, ends_at = $4 - WHERE id = $5 RETURNING id + SET slug = $1, name = $2, description = $3, starts_at = $4, ends_at = $5 + WHERE id = $6 RETURNING id ", + update.slug, update.name, update.description, update.starts_at, update.ends_at, id ) - .fetch_one(pool) + .fetch_one(transaction.deref_mut()) .await?; Ok(()) @@ -118,7 +183,7 @@ impl Campaign { /// Returns the updated campaign pub async fn update_banner( id: i64, - pool: &Pool, + transaction: &mut Transaction<'_, Postgres>, storage_bucket: &Bucket, ) -> Result { let dt = Utc::now(); @@ -135,7 +200,7 @@ impl Campaign { current_time, id ) - .fetch_one(pool) + .fetch_one(transaction.deref_mut()) .await?; let upload_url = @@ -145,14 +210,17 @@ impl Campaign { } /// Delete a campaign from the database - pub async fn delete(id: i64, pool: &Pool) -> Result<(), ChaosError> { + pub async fn delete( + id: i64, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result<(), ChaosError> { _ = sqlx::query!( " DELETE FROM campaigns WHERE id = $1 RETURNING id ", id ) - .fetch_one(pool) + .fetch_one(transaction.deref_mut()) .await?; Ok(()) diff --git a/backend/server/src/models/email_template.rs b/backend/server/src/models/email_template.rs new file mode 100644 index 000000000..dd91cf001 --- /dev/null +++ b/backend/server/src/models/email_template.rs @@ -0,0 +1,114 @@ +use crate::models::error::ChaosError; +use chrono::{DateTime, Local, Utc}; +use handlebars::Handlebars; +use serde::{Deserialize, Serialize}; +use sqlx::{Pool, Postgres, Transaction}; +use std::collections::HashMap; +use std::ops::DerefMut; + +/// Email templates to update applicants +/// Supported tags: +/// - `name` +/// - `role` +/// - `organisation_name` +/// - `expiry_date` +/// - `campaign_name` +#[derive(Deserialize, Serialize)] +pub struct EmailTemplate { + pub id: i64, + pub organisation_id: i64, + pub name: String, + pub template: String, +} + +impl EmailTemplate { + pub async fn get( + id: i64, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result { + let template = sqlx::query_as!( + EmailTemplate, + "SELECT * FROM email_templates WHERE id = $1", + id + ) + .fetch_one(transaction.deref_mut()) + .await?; + + Ok(template) + } + + pub async fn get_all_by_organisation( + organisation_id: i64, + pool: &Pool, + ) -> Result, ChaosError> { + let templates = sqlx::query_as!( + EmailTemplate, + "SELECT * FROM email_templates WHERE organisation_id = $1", + organisation_id + ) + .fetch_all(pool) + .await?; + + Ok(templates) + } + + pub async fn update( + id: i64, + name: String, + template: String, + pool: &Pool, + ) -> Result<(), ChaosError> { + let _ = sqlx::query!( + " + UPDATE email_templates SET name = $2, template = $3 WHERE id = $1 RETURNING id + ", + id, + name, + template + ) + .fetch_one(pool) + .await?; + + Ok(()) + } + + pub async fn delete(id: i64, pool: &Pool) -> Result<(), ChaosError> { + let _ = sqlx::query!("DELETE FROM email_templates WHERE id = $1 RETURNING id", id) + .fetch_one(pool) + .await?; + + Ok(()) + } + + pub async fn generate_email( + name: String, + role: String, + organisation_name: String, + campaign_name: String, + expiry_date: DateTime, + email_template_id: i64, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result { + let template = EmailTemplate::get(email_template_id, transaction).await?; + + let mut handlebars = Handlebars::new(); + handlebars.register_template_string("template", template.template)?; + + let mut data = HashMap::new(); + data.insert("name", name); + data.insert("role", role); + data.insert("organisation_name", organisation_name); + data.insert("campaign_name", campaign_name); + data.insert( + "expiry_date", + expiry_date + .with_timezone(&Local) + .format("%d/%m/%Y %H:%M") + .to_string(), + ); + + let final_string = handlebars.render("template", &data)?; + + Ok(final_string) + } +} diff --git a/backend/server/src/models/error.rs b/backend/server/src/models/error.rs index d541562b2..25f3f7940 100644 --- a/backend/server/src/models/error.rs +++ b/backend/server/src/models/error.rs @@ -39,6 +39,12 @@ pub enum ChaosError { #[error("DotEnvy error")] DotEnvyError(#[from] dotenvy::Error), + + #[error("Templating error")] + TemplateError(#[from] handlebars::TemplateError), + + #[error("Template rendering error")] + TemplateRendorError(#[from] handlebars::RenderError), } /// Implementation for converting errors into responses. Manages error code and message returned. diff --git a/backend/server/src/models/mod.rs b/backend/server/src/models/mod.rs index 9f30a8bba..e2d03ca5a 100644 --- a/backend/server/src/models/mod.rs +++ b/backend/server/src/models/mod.rs @@ -3,7 +3,9 @@ pub mod app; pub mod application; pub mod auth; pub mod campaign; +pub mod email_template; pub mod error; +pub mod offer; pub mod organisation; pub mod question; pub mod rating; diff --git a/backend/server/src/models/offer.rs b/backend/server/src/models/offer.rs new file mode 100644 index 000000000..d02017562 --- /dev/null +++ b/backend/server/src/models/offer.rs @@ -0,0 +1,223 @@ +use crate::models::email_template::EmailTemplate; +use crate::models::error::ChaosError; +use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; +use snowflake::SnowflakeIdGenerator; +use sqlx::{Postgres, Transaction}; +use std::ops::DerefMut; + +#[derive(Deserialize)] +pub struct Offer { + pub id: i64, + pub campaign_id: i64, + pub application_id: i64, + pub email_template_id: i64, + pub role_id: i64, + pub expiry: DateTime, + pub status: OfferStatus, + pub created_at: DateTime, +} + +#[derive(Deserialize, Serialize)] +pub struct OfferDetails { + pub id: i64, + pub campaign_id: i64, + pub organisation_name: String, + pub campaign_name: String, + pub application_id: i64, + pub user_id: i64, + pub user_name: String, + pub user_email: String, + pub email_template_id: i64, + pub role_id: i64, + pub role_name: String, + pub expiry: DateTime, + pub status: OfferStatus, + pub created_at: DateTime, +} + +#[derive(Deserialize, Serialize, sqlx::Type, Clone, Debug)] +#[sqlx(type_name = "offer_status", rename_all = "PascalCase")] +pub enum OfferStatus { + Draft, + Sent, + Accepted, + Declined, +} + +#[derive(Deserialize)] +pub struct OfferReply { + pub accept: bool, +} + +impl Offer { + pub async fn create( + campaign_id: i64, + application_id: i64, + email_template_id: i64, + role_id: i64, + expiry: DateTime, + transaction: &mut Transaction<'_, Postgres>, + mut snowflake_id_generator: SnowflakeIdGenerator, + ) -> Result { + let id = snowflake_id_generator.real_time_generate(); + + let _ = sqlx::query!( + " + INSERT INTO offers (id, campaign_id, application_id, email_template_id, role_id, expiry) VALUES ($1, $2, $3, $4, $5, $6) + ", + id, + campaign_id, + application_id, + email_template_id, + role_id, + expiry + ) + .execute(transaction.deref_mut()) + .await?; + + Ok(id) + } + + pub async fn get( + id: i64, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result { + let offer = sqlx::query_as!( + OfferDetails, + r#" + SELECT + off.id, off.campaign_id, off.application_id, off.email_template_id, + off.role_id, off.expiry, off.created_at, + off.status AS "status!: OfferStatus", + c.name as campaign_name, + o.name as organisation_name, + u.id as user_id, + u.name as user_name, + u.email as user_email, + r.name as role_name + FROM offers off + JOIN campaigns c ON c.id = off.campaign_id + JOIN organisations o ON o.id = c.organisation_id + JOIN applications a ON a.id = off.application_id + JOIN users u ON u.id = a.user_id + JOIN campaign_roles r ON r.id = off.role_id + WHERE off.id = $1 + "#, + id + ) + .fetch_one(transaction.deref_mut()) + .await?; + + Ok(offer) + } + + pub async fn get_by_campaign( + campaign_id: i64, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result, ChaosError> { + let offers = sqlx::query_as!( + OfferDetails, + r#" + SELECT + off.id, off.campaign_id, off.application_id, off.email_template_id, + off.role_id, off.expiry, off.created_at, + off.status AS "status!: OfferStatus", + c.name as campaign_name, + o.name as organisation_name, + u.id as user_id, + u.name as user_name, + u.email as user_email, + r.name as role_name + FROM offers off + JOIN campaigns c on c.id = off.campaign_id + JOIN organisations o on o.id = c.organisation_id + JOIN applications a ON a.id = off.application_id + JOIN users u on u.id = a.user_id + JOIN campaign_roles r on r.id = off.role_id + WHERE off.id = $1 + "#, + campaign_id + ) + .fetch_all(transaction.deref_mut()) + .await?; + + Ok(offers) + } + + pub async fn delete( + id: i64, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result<(), ChaosError> { + let _ = sqlx::query!("DELETE FROM offers WHERE id = $1 RETURNING id", id) + .fetch_one(transaction.deref_mut()) + .await?; + + Ok(()) + } + + pub async fn reply( + id: i64, + accept: bool, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result<(), ChaosError> { + let offer = Offer::get(id, transaction).await?; + + if Utc::now() > offer.expiry { + return Err(ChaosError::BadRequest); + } + + let mut status = OfferStatus::Accepted; + if !accept { + status = OfferStatus::Declined; + } + + let _ = sqlx::query!( + "UPDATE offers SET status = $2 WHERE id = $1", + id, + status as OfferStatus + ) + .execute(transaction.deref_mut()) + .await?; + + Ok(()) + } + + pub async fn preview_email( + id: i64, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result { + let offer = Offer::get(id, transaction).await?; + let email = EmailTemplate::generate_email( + offer.user_name, + offer.role_name, + offer.organisation_name, + offer.campaign_name, + offer.expiry, + offer.email_template_id, + transaction, + ) + .await?; + Ok(email) + } + + pub async fn send_offer( + id: i64, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result<(), ChaosError> { + let offer = Offer::get(id, transaction).await?; + let email = EmailTemplate::generate_email( + offer.user_name, + offer.role_name, + offer.organisation_name, + offer.campaign_name, + offer.expiry, + offer.email_template_id, + transaction, + ) + .await?; + + // TODO: Send email e.g. send_email(offer.user_email, email).await?; + Ok(()) + } +} diff --git a/backend/server/src/models/organisation.rs b/backend/server/src/models/organisation.rs index 94a34c241..94824c377 100644 --- a/backend/server/src/models/organisation.rs +++ b/backend/server/src/models/organisation.rs @@ -12,6 +12,7 @@ use uuid::Uuid; #[derive(Deserialize, Serialize, Clone, FromRow, Debug)] pub struct Organisation { pub id: i64, + pub slug: String, pub name: String, pub logo: Option, pub created_at: DateTime, @@ -22,6 +23,7 @@ pub struct Organisation { #[derive(Deserialize, Serialize)] pub struct NewOrganisation { + pub slug: String, pub name: String, pub admin: i64, } @@ -29,6 +31,7 @@ pub struct NewOrganisation { #[derive(Deserialize, Serialize)] pub struct OrganisationDetails { pub id: i64, + pub slug: String, pub name: String, pub logo: Option, pub created_at: DateTime, @@ -63,21 +66,32 @@ pub struct AdminToRemove { pub user_id: i64, } +#[derive(Deserialize)] +pub struct SlugCheck { + pub slug: String, +} + impl Organisation { pub async fn create( admin_id: i64, + slug: String, name: String, mut snowflake_generator: SnowflakeIdGenerator, transaction: &mut Transaction<'_, Postgres>, ) -> Result<(), ChaosError> { + if !slug.is_ascii() { + return Err(ChaosError::BadRequest); + } + let id = snowflake_generator.generate(); sqlx::query!( " - INSERT INTO organisations (id, name) - VALUES ($1, $2) + INSERT INTO organisations (id, slug, name) + VALUES ($1, $2, $3) ", id, + slug, name ) .execute(transaction.deref_mut()) @@ -98,11 +112,37 @@ impl Organisation { Ok(()) } + pub async fn check_slug_availability( + slug: String, + pool: &Pool, + ) -> Result<(), ChaosError> { + if !slug.is_ascii() { + return Err(ChaosError::BadRequest); + } + + let exists = sqlx::query!( + " + SELECT EXISTS(SELECT 1 FROM organisations WHERE slug = $1) + ", + slug + ) + .fetch_one(pool) + .await? + .exists + .expect("`exists` should always exist in this query result"); + + if exists { + return Err(ChaosError::BadRequest); + } + + Ok(()) + } + pub async fn get(id: i64, pool: &Pool) -> Result { let organisation = sqlx::query_as!( OrganisationDetails, " - SELECT id, name, logo, created_at + SELECT id, slug, name, logo, created_at FROM organisations WHERE id = $1 ", @@ -114,6 +154,25 @@ impl Organisation { Ok(organisation) } + pub async fn get_by_slug( + slug: String, + pool: &Pool, + ) -> Result { + let organisation = sqlx::query_as!( + OrganisationDetails, + " + SELECT id, slug, name, logo, created_at + FROM organisations + WHERE slug = $1 + ", + slug + ) + .fetch_one(pool) + .await?; + + Ok(organisation) + } + pub async fn delete(id: i64, pool: &Pool) -> Result<(), ChaosError> { _ = sqlx::query!( " @@ -330,7 +389,7 @@ impl Organisation { let campaigns = sqlx::query_as!( OrganisationCampaign, " - SELECT id, name, cover_image, description, starts_at, ends_at + SELECT id, slug, name, cover_image, description, starts_at, ends_at FROM campaigns WHERE organisation_id = $1 ", @@ -344,22 +403,28 @@ impl Organisation { pub async fn create_campaign( organisation_id: i64, + slug: String, name: String, description: Option, starts_at: DateTime, ends_at: DateTime, pool: &Pool, - snowflake_id_generator: &mut SnowflakeIdGenerator, + mut snowflake_id_generator: SnowflakeIdGenerator, ) -> Result<(), ChaosError> { + if !slug.is_ascii() { + return Err(ChaosError::BadRequest); + } + let new_campaign_id = snowflake_id_generator.real_time_generate(); sqlx::query!( " - INSERT INTO campaigns (id, organisation_id, name, description, starts_at, ends_at) - VALUES ($1, $2, $3, $4, $5, $6) + INSERT INTO campaigns (id, organisation_id, slug, name, description, starts_at, ends_at) + VALUES ($1, $2, $3, $4, $5, $6, $7) ", new_campaign_id, organisation_id, + slug, name, description, starts_at, @@ -370,4 +435,29 @@ impl Organisation { Ok(()) } + + pub async fn create_email_template( + organisation_id: i64, + name: String, + template: String, + pool: &Pool, + mut snowflake_generator: SnowflakeIdGenerator, + ) -> Result { + let id = snowflake_generator.generate(); + + let _ = sqlx::query!( + " + INSERT INTO email_templates (id, organisation_id, name, template) + VALUES ($1, $2, $3, $4) + ", + id, + organisation_id, + name, + template + ) + .execute(pool) + .await?; + + Ok(id) + } } diff --git a/backend/server/src/models/role.rs b/backend/server/src/models/role.rs index ff53014b8..ec07082ed 100644 --- a/backend/server/src/models/role.rs +++ b/backend/server/src/models/role.rs @@ -2,7 +2,8 @@ use crate::models::error::ChaosError; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use snowflake::SnowflakeIdGenerator; -use sqlx::{FromRow, Pool, Postgres}; +use sqlx::{FromRow, Pool, Postgres, Transaction}; +use std::ops::DerefMut; #[derive(Deserialize, Serialize, Clone, FromRow, Debug)] pub struct Role { @@ -41,7 +42,7 @@ impl Role { pub async fn create( campaign_id: i64, role_data: RoleUpdate, - pool: &Pool, + transaction: &mut Transaction<'_, Postgres>, mut snowflake_generator: SnowflakeIdGenerator, ) -> Result<(), ChaosError> { let id = snowflake_generator.generate(); @@ -59,7 +60,7 @@ impl Role { role_data.max_avaliable, role_data.finalised ) - .execute(pool) + .execute(transaction.deref_mut()) .await?; Ok(()) @@ -123,7 +124,7 @@ impl Role { */ pub async fn get_all_in_campaign( campaign_id: i64, - pool: &Pool, + transaction: &mut Transaction<'_, Postgres>, ) -> Result, ChaosError> { let roles = sqlx::query_as!( RoleDetails, @@ -134,7 +135,7 @@ impl Role { ", campaign_id ) - .fetch_all(pool) + .fetch_all(transaction.deref_mut()) .await?; Ok(roles) diff --git a/backend/server/src/service/auth.rs b/backend/server/src/service/auth.rs index cf136cfd2..68b9302f2 100644 --- a/backend/server/src/service/auth.rs +++ b/backend/server/src/service/auth.rs @@ -1,5 +1,11 @@ +use crate::models::app::AppState; +use crate::models::error::ChaosError; use crate::models::user::UserRole; -use anyhow::Result; +use crate::service::jwt::decode_auth_token; +use axum::http::request::Parts; +use axum::RequestPartsExt; +use axum_extra::headers::Cookie; +use axum_extra::TypedHeader; use snowflake::SnowflakeIdGenerator; use sqlx::{Pool, Postgres}; @@ -13,7 +19,7 @@ pub async fn create_or_get_user_id( name: String, pool: Pool, mut snowflake_generator: SnowflakeIdGenerator, -) -> Result { +) -> Result { let possible_user_id = sqlx::query!( "SELECT id FROM users WHERE lower(email) = $1", email.to_lowercase() @@ -39,14 +45,39 @@ pub async fn create_or_get_user_id( Ok(user_id) } -pub async fn is_super_user(user_id: i64, pool: &Pool) -> Result { +pub async fn assert_is_super_user(user_id: i64, pool: &Pool) -> Result<(), ChaosError> { let is_super_user = sqlx::query!( "SELECT EXISTS(SELECT 1 FROM users WHERE id = $1 AND role = $2)", user_id, UserRole::SuperUser as UserRole ) .fetch_one(pool) - .await?; + .await? + .exists + .expect("`exists` should always exist in this query result"); + + if !is_super_user { + return Err(ChaosError::Unauthorized); + } + + Ok(()) +} + +pub async fn extract_user_id_from_request( + parts: &mut Parts, + state: &AppState, +) -> Result { + let decoding_key = &state.decoding_key; + let jwt_validator = &state.jwt_validator; + let TypedHeader(cookies) = parts + .extract::>() + .await + .map_err(|_| ChaosError::NotLoggedIn)?; + + let token = cookies.get("auth_token").ok_or(ChaosError::NotLoggedIn)?; + + let claims = + decode_auth_token(token, decoding_key, jwt_validator).ok_or(ChaosError::NotLoggedIn)?; - Ok(is_super_user.exists.unwrap()) + Ok(claims.sub) } diff --git a/backend/server/src/service/email_template.rs b/backend/server/src/service/email_template.rs new file mode 100644 index 000000000..3ef19e2a3 --- /dev/null +++ b/backend/server/src/service/email_template.rs @@ -0,0 +1,30 @@ +use crate::models::error::ChaosError; +use sqlx::{Pool, Postgres}; + +pub async fn user_is_email_template_admin( + user_id: i64, + template_id: i64, + pool: &Pool, +) -> Result<(), ChaosError> { + let is_admin = sqlx::query!( + " + SELECT EXISTS( + SELECT 1 FROM email_templates et + JOIN organisation_members m on et.organisation_id = m.organisation_id + WHERE et.id = $1 AND m.user_id = $2 AND m.role = 'Admin' + ) + ", + template_id, + user_id + ) + .fetch_one(pool) + .await? + .exists + .expect("`exists` should always exist in this query result"); + + if !is_admin { + return Err(ChaosError::Unauthorized); + } + + Ok(()) +} diff --git a/backend/server/src/service/mod.rs b/backend/server/src/service/mod.rs index 8fd957f68..e4ad67699 100644 --- a/backend/server/src/service/mod.rs +++ b/backend/server/src/service/mod.rs @@ -2,8 +2,10 @@ pub mod answer; pub mod application; pub mod auth; pub mod campaign; +pub mod email_template; pub mod jwt; pub mod oauth2; +pub mod offer; pub mod organisation; pub mod question; pub mod rating; diff --git a/backend/server/src/service/offer.rs b/backend/server/src/service/offer.rs new file mode 100644 index 000000000..f044ea7ba --- /dev/null +++ b/backend/server/src/service/offer.rs @@ -0,0 +1,47 @@ +use crate::models::error::ChaosError; +use crate::models::offer::Offer; +use sqlx::{Pool, Postgres}; + +pub async fn assert_user_is_offer_admin( + user_id: i64, + offer_id: i64, + pool: &Pool, +) -> Result<(), ChaosError> { + let is_admin = sqlx::query!( + " + SELECT EXISTS( + SELECT 1 FROM offers off + JOIN campaigns c ON c.id = off.campaign_id + JOIN organisation_members m on c.organisation_id = m.organisation_id + WHERE off.id = $1 AND m.user_id = $2 AND m.role = 'Admin' + ) + ", + offer_id, + user_id + ) + .fetch_one(pool) + .await? + .exists + .expect("`exists` should always exist in this query result"); + + if !is_admin { + return Err(ChaosError::Unauthorized); + } + + Ok(()) +} + +pub async fn assert_user_is_offer_recipient( + user_id: i64, + offer_id: i64, + pool: &Pool, +) -> Result<(), ChaosError> { + let tx = &mut pool.begin().await?; + let offer = Offer::get(offer_id, tx).await?; + + if offer.user_id != user_id { + return Err(ChaosError::Unauthorized); + } + + Ok(()) +} From 877c388328eb692a61b739d1302812ab3bbdec72 Mon Sep 17 00:00:00 2001 From: Kavika Date: Mon, 30 Dec 2024 19:36:08 +0530 Subject: [PATCH 38/56] optional user pronouns and gender --- backend/migrations/20240406023149_create_users.sql | 6 +++--- backend/server/src/models/application.rs | 4 ++-- backend/server/src/models/user.rs | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/backend/migrations/20240406023149_create_users.sql b/backend/migrations/20240406023149_create_users.sql index 94fa0440d..49dad0f43 100644 --- a/backend/migrations/20240406023149_create_users.sql +++ b/backend/migrations/20240406023149_create_users.sql @@ -5,11 +5,11 @@ CREATE TABLE users ( email TEXT NOT NULL UNIQUE, zid TEXT, name TEXT NOT NULL, - pronouns TEXT NOT NULL, - gender TEXT NOT NULL, + pronouns TEXT, + gender TEXT, degree_name TEXT, degree_starting_year INTEGER, - role user_role NOT NULL, + role user_role NOT NULL DEFAULT 'User', created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP ); diff --git a/backend/server/src/models/application.rs b/backend/server/src/models/application.rs index 1cd9a74f0..c5f86906c 100644 --- a/backend/server/src/models/application.rs +++ b/backend/server/src/models/application.rs @@ -52,8 +52,8 @@ pub struct ApplicationData { pub user_email: String, pub user_zid: Option, pub user_name: String, - pub user_pronouns: String, - pub user_gender: String, + pub user_pronouns: Option, + pub user_gender: Option, pub user_degree_name: Option, pub user_degree_starting_year: Option, pub status: ApplicationStatus, diff --git a/backend/server/src/models/user.rs b/backend/server/src/models/user.rs index cf5fb8e4f..dd01c074a 100644 --- a/backend/server/src/models/user.rs +++ b/backend/server/src/models/user.rs @@ -15,8 +15,8 @@ pub struct UserDetails { pub email: String, pub zid: Option, pub name: String, - pub pronouns: String, - pub gender: String, + pub pronouns: Option, + pub gender: Option, pub degree_name: Option, pub degree_starting_year: Option, } @@ -27,8 +27,8 @@ pub struct User { pub email: String, pub zid: Option, pub name: String, - pub pronouns: String, - pub gender: String, + pub pronouns: Option, + pub gender: Option, pub degree_name: Option, pub degree_starting_year: Option, pub role: UserRole, From 6ee51b2ef46f93d3b36b0aee587fee2f1c464ae6 Mon Sep 17 00:00:00 2001 From: Kavika Date: Mon, 30 Dec 2024 19:37:22 +0530 Subject: [PATCH 39/56] move `oauth2_client` to `AppState` --- backend/server/src/handler/auth.rs | 10 +++------- backend/server/src/models/app.rs | 13 +++++++++++++ backend/server/src/service/oauth2.rs | 4 +--- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/backend/server/src/handler/auth.rs b/backend/server/src/handler/auth.rs index 12fcab02a..b7b4187d5 100644 --- a/backend/server/src/handler/auth.rs +++ b/backend/server/src/handler/auth.rs @@ -5,8 +5,6 @@ use crate::service::auth::create_or_get_user_id; use crate::service::jwt::encode_auth_token; use axum::extract::{Query, State}; use axum::response::IntoResponse; -use axum::Extension; -use oauth2::basic::BasicClient; use oauth2::reqwest::async_http_client; use oauth2::{AuthorizationCode, TokenResponse}; @@ -16,9 +14,8 @@ use oauth2::{AuthorizationCode, TokenResponse}; pub async fn google_callback( State(state): State, Query(query): Query, - Extension(oauth_client): Extension, ) -> Result { - let token = oauth_client + let token = state.oauth2_client .exchange_code(AuthorizationCode::new(query.code)) .request_async(async_http_client) .await?; @@ -30,7 +27,7 @@ pub async fn google_callback( .send() .await?; - let profile = profile.json::().await.unwrap(); + let profile = profile.json::().await?; let user_id = create_or_get_user_id( profile.email.clone(), @@ -38,8 +35,7 @@ pub async fn google_callback( state.db, state.snowflake_generator, ) - .await - .unwrap(); + .await?; // TODO: Return JWT as set-cookie header. let token = encode_auth_token( diff --git a/backend/server/src/models/app.rs b/backend/server/src/models/app.rs index 5fd59143f..14e159108 100644 --- a/backend/server/src/models/app.rs +++ b/backend/server/src/models/app.rs @@ -20,11 +20,14 @@ use snowflake::SnowflakeIdGenerator; use sqlx::postgres::PgPoolOptions; use sqlx::{Pool, Postgres}; use std::env; +use oauth2::basic::BasicClient; +use crate::service::oauth2::build_oauth_client; #[derive(Clone)] pub struct AppState { pub db: Pool, pub ctx: ReqwestClient, + pub oauth2_client: BasicClient, pub decoding_key: DecodingKey, pub encoding_key: EncodingKey, pub jwt_header: Header, @@ -59,6 +62,15 @@ pub async fn app() -> Result { // Initialise reqwest client let ctx = reqwest::Client::new(); + // Initialise oauth2 client + let client_id = env::var("GOOGLE_CLIENT_ID") + .expect("Error getting GOOGLE_CLIENT_ID") + .to_string(); + let client_secret = env::var("GOOGLE_CLIENT_SECRET") + .expect("Error getting GOOGLE_CLIENT_SECRET") + .to_string(); + let oauth2_client = build_oauth_client(client_id, client_secret); + // Initialise Snowflake Generator let snowflake_generator = SnowflakeIdGenerator::new(1, 1); @@ -69,6 +81,7 @@ pub async fn app() -> Result { let state = AppState { db: pool, ctx, + oauth2_client, encoding_key, decoding_key, jwt_header, diff --git a/backend/server/src/service/oauth2.rs b/backend/server/src/service/oauth2.rs index 43c1104c7..58e56e49e 100644 --- a/backend/server/src/service/oauth2.rs +++ b/backend/server/src/service/oauth2.rs @@ -7,9 +7,7 @@ use std::env; /// Client follows OAuth2 Standard (https://oauth.net/2/) to get user's email /// using OpenID Connect (https://openid.net/developers/how-connect-works/). pub fn build_oauth_client(client_id: String, client_secret: String) -> BasicClient { - let hostname = env::var("CHAOS_HOSTNAME").expect("Could not read CHAOS hostname"); - - let redirect_url = format!("{}/api/auth/callback/google", hostname); + let redirect_url = env::var("GOOGLE_REDIRECT_URI").expect("Could not read GOOGLE_REDIRECT_URI"); let auth_url = AuthUrl::new("https://accounts.google.com/o/oauth2/v2/auth".to_string()) .expect("Invalid authorization endpoint URL"); From 98650af5308d8d7fef284f044a0c81c7d1caeb8f Mon Sep 17 00:00:00 2001 From: gyoumi <87557702+Gyoumi@users.noreply.github.com> Date: Mon, 21 Apr 2025 03:24:43 +1000 Subject: [PATCH 40/56] committing most up to date working frontend (#546) --- frontend/.eslintrc.json | 62 +- frontend/index.html | 2 +- frontend/package.json | 5 +- frontend/prettier.config.js | 19 +- frontend/public/site.webmanifest | 20 +- frontend/src/api/api.ts | 5 +- .../src/assets/LandingPage/janestreet.png | Bin 0 -> 12404 bytes frontend/src/assets/LandingPage/tiktok.svg | 1 + frontend/src/components/Button.tsx | 11 +- .../CampaignCard/CampaignStatus.tsx | 8 +- .../src/components/CampaignCard/Content.tsx | 14 +- frontend/src/components/Card.tsx | 2 +- frontend/src/components/Container.tsx | 2 +- .../components/Dropdown/DropdownOption.tsx | 5 +- frontend/src/components/Dropdown/index.tsx | 3 +- frontend/src/components/Dropzone.tsx | 2 +- frontend/src/components/Input.tsx | 11 +- frontend/src/components/Link.tsx | 6 +- .../src/components/LoadingIndicator/index.tsx | 2 +- frontend/src/components/Modal/index.tsx | 4 +- .../src/components/NavBar/AvatarButton.tsx | 30 +- frontend/src/components/NavBar/index.tsx | 36 +- frontend/src/components/NavCard/NavItem.tsx | 8 +- frontend/src/components/Tabs.tsx | 7 +- frontend/src/components/Textarea.tsx | 12 +- frontend/src/components/Toast.tsx | 16 +- .../AdminContent/AdminCampaignContent.tsx | 2 +- .../src/pages/admin/AdminContent/index.tsx | 12 +- frontend/src/pages/admin/AdminLoading.tsx | 4 +- .../review/finalise_candidates/index.tsx | 10 +- .../finalRatingCandidateCard.styled.ts | 16 +- .../application_page/ApplicationForm.tsx | 6 +- .../ApplicationPageLoading.tsx | 8 +- .../application_page/CampaignDetails.tsx | 16 +- .../CampaignGrid/CampaignLoading.tsx | 8 +- frontend/src/pages/dashboard/index.tsx | 2 +- .../landing/components/Campaigns/Campaign.tsx | 8 +- .../landing/components/Campaigns/index.tsx | 12 +- .../landing/components/DashboardButton.tsx | 19 +- .../pages/landing/components/SponsorLogos.tsx | 22 + frontend/src/pages/landing/index.tsx | 27 +- .../pages/signup/SignupGenderSelection.tsx | 6 +- frontend/src/pages/signup/index.tsx | 2 +- frontend/src/utils/index.tsx | 4 +- frontend/tailwind.config.js | 26 +- frontend/types/twin.d.ts | 100 +- frontend/yarn.lock | 1442 +++++++++++------ 47 files changed, 1299 insertions(+), 746 deletions(-) create mode 100644 frontend/src/assets/LandingPage/janestreet.png create mode 100644 frontend/src/assets/LandingPage/tiktok.svg create mode 100644 frontend/src/pages/landing/components/SponsorLogos.tsx diff --git a/frontend/.eslintrc.json b/frontend/.eslintrc.json index 59ac65a75..2a2ef1315 100644 --- a/frontend/.eslintrc.json +++ b/frontend/.eslintrc.json @@ -14,6 +14,13 @@ "plugin:import/typescript", "plugin:react/jsx-runtime" ], + "ignorePatterns": [ + "babel-plugin-macros.config.js", + "tailwind.config.js", + "prettier.config.js", + "postcss.config.js", + "vite.config.ts" + ], "parser": "@typescript-eslint/parser", "parserOptions": { "ecmaVersion": 12, @@ -32,42 +39,43 @@ "@typescript-eslint/no-shadow": "off", "no-unused-vars": "off", "@typescript-eslint/no-unused-vars": [ - 1, + "warn", { "varsIgnorePattern": "^_", "argsIgnorePattern": "^_" } ], "@typescript-eslint/naming-convention": [ - "error", - { - "selector": "default", - "format": ["camelCase"], - "leadingUnderscore": "allow", - "trailingUnderscore": "allow" - }, + "error", + { + "selector": "default", + "format": ["camelCase"], + "leadingUnderscore": "allow", + "trailingUnderscore": "allow" + }, - { - "selector": "variable", - "format": ["camelCase", "UPPER_CASE", "PascalCase"], - "leadingUnderscore": "allow", - "trailingUnderscore": "allow" - }, + { + "selector": "variable", + "format": ["camelCase", "UPPER_CASE", "PascalCase"], + "leadingUnderscore": "allow", + "trailingUnderscore": "allow" + }, - { - "selector": "function", - "format": ["camelCase", "PascalCase"] - }, + { + "selector": "function", + "format": ["camelCase", "PascalCase"] + }, - { - "selector": "typeLike", - "format": ["PascalCase"] - }, + { + "selector": "typeLike", + "format": ["PascalCase"], + "leadingUnderscore": "allow" + }, - { - "selector": "objectLiteralProperty", - "format": null - } + { + "selector": "objectLiteralProperty", + "format": null + } ], "import/prefer-default-export": "off", "import/no-extraneous-dependencies": ["error", { "devDependencies": true }], @@ -103,7 +111,7 @@ "custom": "ignore" } ], - "react/no-unknown-property": [2, { "ignore": ["tw", "css"] }], + "react/no-unknown-property": ["error", { "ignore": ["tw", "css"] }], "react/require-default-props": "off", "@typescript-eslint/consistent-type-imports": "error", "no-void": "off", diff --git a/frontend/index.html b/frontend/index.html index 3a7f74719..948097a63 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -1,4 +1,4 @@ - + diff --git a/frontend/package.json b/frontend/package.json index 858b5a3a2..a0f491d50 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -79,11 +79,12 @@ "eslint-import-resolver-typescript": "3.5.2", "eslint-plugin-import": "2.27.5", "eslint-plugin-jsx-a11y": "6.7.1", - "eslint-plugin-prettier": "4.2.1", + "eslint-plugin-prettier": "5.0.0", "eslint-plugin-react": "7.32.2", "eslint-plugin-react-hooks": "4.6.0", "husky": "8.0.2", - "prettier": "2.8.0", + "prettier": "3.3.2", + "prettier-plugin-tailwindcss": "0.6.4", "tailwindcss": "3.3.2", "tailwindcss-gradient": "1.0.1", "twin.macro": "3.3.1", diff --git a/frontend/prettier.config.js b/frontend/prettier.config.js index 0b8f2b0b7..1a41a1189 100644 --- a/frontend/prettier.config.js +++ b/frontend/prettier.config.js @@ -1,3 +1,20 @@ +/** + * @type {import("prettier").Config} + */ module.exports = { - plugins: [], + trailingComma: "es5", + tabWidth: 2, + semi: true, + singleQuote: false, + printWidth: 80, + useTabs: false, + quoteProps: "as-needed", + jsxSingleQuote: false, + bracketSpacing: true, + bracketSameLine: false, + arrowParens: "always", + + plugins: ["prettier-plugin-tailwindcss"], + tailwindAttributes: ["className", "class", "tw"], + tailwindFunctions: ["tw"], }; diff --git a/frontend/public/site.webmanifest b/frontend/public/site.webmanifest index 45dc8a206..fa99de77d 100644 --- a/frontend/public/site.webmanifest +++ b/frontend/public/site.webmanifest @@ -1 +1,19 @@ -{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} \ No newline at end of file +{ + "name": "", + "short_name": "", + "icons": [ + { + "src": "/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} diff --git a/frontend/src/api/api.ts b/frontend/src/api/api.ts index 6ae704778..4cfa7fed3 100644 --- a/frontend/src/api/api.ts +++ b/frontend/src/api/api.ts @@ -5,7 +5,10 @@ export class FetchError extends Error { public statusText: string; - constructor(public resp: Response, public data?: unknown) { + constructor( + public resp: Response, + public data?: unknown + ) { super(resp.statusText); this.name = "FetchError"; diff --git a/frontend/src/assets/LandingPage/janestreet.png b/frontend/src/assets/LandingPage/janestreet.png new file mode 100644 index 0000000000000000000000000000000000000000..8533efd5f4844673d043943dadc47bffa17a625a GIT binary patch literal 12404 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 Bl{o+a literal 0 HcmV?d00001 diff --git a/frontend/src/assets/LandingPage/tiktok.svg b/frontend/src/assets/LandingPage/tiktok.svg new file mode 100644 index 000000000..93d551a82 --- /dev/null +++ b/frontend/src/assets/LandingPage/tiktok.svg @@ -0,0 +1 @@ + diff --git a/frontend/src/components/Button.tsx b/frontend/src/components/Button.tsx index 5d0387f19..d810d0a82 100644 --- a/frontend/src/components/Button.tsx +++ b/frontend/src/components/Button.tsx @@ -1,20 +1,13 @@ import tw, { styled } from "twin.macro"; const Button = styled.button({ - ...tw` - px-3 py-1.5 flex items-center gap-1 rounded shadow transition outline-none - disabled:(opacity-50 cursor-not-allowed) focus:ring - `, + ...tw`flex items-center gap-1 rounded px-3 py-1.5 shadow outline-none transition focus:ring disabled:cursor-not-allowed disabled:opacity-50`, variants: { color: { primary: tw`bg-brand-500 text-white ring-brand-500/40 hover:bg-brand-600 active:bg-brand-700`, danger: tw`bg-red-600 text-white ring-red-600/40 hover:bg-red-700 active:bg-red-800`, - white: tw` - bg-white border border-brand-300 text-gray-900 ring-brand-300/40 - hover:(bg-brand-50 text-brand-950 border-brand-400) - active:bg-brand-75 - `, + white: tw`border border-brand-300 bg-white text-gray-900 ring-brand-300/40 hover:border-brand-400 hover:bg-brand-50 hover:text-brand-950 active:bg-brand-75`, }, }, diff --git a/frontend/src/components/CampaignCard/CampaignStatus.tsx b/frontend/src/components/CampaignCard/CampaignStatus.tsx index 1522a1019..81c30b52c 100644 --- a/frontend/src/components/CampaignCard/CampaignStatus.tsx +++ b/frontend/src/components/CampaignCard/CampaignStatus.tsx @@ -1,15 +1,15 @@ import tw, { styled } from "twin.macro"; const CampaignStatus = styled.button({ - ...tw`ml-auto flex items-center gap-1 px-2 py-1.5 text-white rounded-[0.2rem] shadow transition hover:shadow-md`, + ...tw`ml-auto flex items-center gap-1 rounded-[0.2rem] px-2 py-1.5 text-white shadow transition hover:shadow-md`, variants: { status: { - pending: tw`text-black bg-[hsl(220, 60%, 90%)] shadow-[hsl(220, 60%, 90%)]!`, + pending: tw`bg-[hsl(220, 60%, 90%)] shadow-[hsl(220, 60%, 90%)]! text-black`, open: tw`bg-[hsl(220, 93%, 60%)] shadow-[hsla(220, 93%, 60%, 50%)]!`, closed: tw`bg-gray-100 text-black`, - offered: tw`bg-green-200 text-green-900 shadow-green-200! hover:bg-green-300`, - rejected: tw`bg-red-200 text-red-900 shadow-red-200!`, + offered: tw`shadow-green-200! bg-green-200 text-green-900 hover:bg-green-300`, + rejected: tw`shadow-red-200! bg-red-200 text-red-900`, }, }, diff --git a/frontend/src/components/CampaignCard/Content.tsx b/frontend/src/components/CampaignCard/Content.tsx index 73873bfa7..8a9ff8425 100644 --- a/frontend/src/components/CampaignCard/Content.tsx +++ b/frontend/src/components/CampaignCard/Content.tsx @@ -180,12 +180,12 @@ const Content = ({ } + icon={} onClick={() => setShowEditDialog(true)} /> } + icon={} onClick={() => setShowDeleteDialog(true)} /> @@ -193,10 +193,10 @@ const Content = ({ return ( <> - +

Organisation @@ -214,9 +214,9 @@ const Content = ({ )}
-
+
Campaign Cover @@ -238,7 +238,7 @@ const Content = ({

) : ( campaign cover diff --git a/frontend/src/components/Card.tsx b/frontend/src/components/Card.tsx index 27151dd04..11d58ddf7 100644 --- a/frontend/src/components/Card.tsx +++ b/frontend/src/components/Card.tsx @@ -5,7 +5,7 @@ const Card = styled.div({ variants: { hoverable: { - true: tw`transition hover:(-translate-y-1 shadow-lg)`, + true: tw`transition hover:-translate-y-1 hover:shadow-lg`, }, }, }); diff --git a/frontend/src/components/Container.tsx b/frontend/src/components/Container.tsx index 2900d7490..4e6dc7885 100644 --- a/frontend/src/components/Container.tsx +++ b/frontend/src/components/Container.tsx @@ -1,3 +1,3 @@ import tw from "twin.macro"; -export default tw.div`flex flex-col flex-1 max-w-7xl mx-auto p-4`; +export default tw.div`mx-auto flex max-w-7xl flex-1 flex-col p-4`; diff --git a/frontend/src/components/Dropdown/DropdownOption.tsx b/frontend/src/components/Dropdown/DropdownOption.tsx index 246a5c983..c88c14b99 100644 --- a/frontend/src/components/Dropdown/DropdownOption.tsx +++ b/frontend/src/components/Dropdown/DropdownOption.tsx @@ -1,9 +1,8 @@ import { Menu } from "@headlessui/react"; +import tw from "twin.macro"; import type { ComponentProps, MouseEvent, ReactElement } from "react"; -import tw from "twin.macro"; - type Props = { name: string; onClick: () => void; @@ -14,7 +13,7 @@ const DropdownOption = ({ name, onClick, icon, ...props }: Props) => ( {({ close }) => (
diff --git a/frontend/src/components/NavCard/NavItem.tsx b/frontend/src/components/NavCard/NavItem.tsx index 1150bb723..b2f093b4e 100644 --- a/frontend/src/components/NavCard/NavItem.tsx +++ b/frontend/src/components/NavCard/NavItem.tsx @@ -6,16 +6,12 @@ const NavItem = styled.div({ ...tw`relative z-0 hover:before:opacity-20`, "&::before": { content: "", - ...tw` - absolute inset-0 z-[-1] - bg-gradient-to-r from-blue-300 to-violet-300 - rounded opacity-0 transition-opacity - `, + ...tw`absolute inset-0 z-[-1] rounded bg-gradient-to-r from-blue-300 to-violet-300 opacity-0 transition-opacity`, }, variants: { active: { - true: tw`shadow-sm before:opacity-30!`, + true: tw`before:opacity-30! shadow-sm`, }, }, }); diff --git a/frontend/src/components/Tabs.tsx b/frontend/src/components/Tabs.tsx index 7f229b2a8..e7bcee156 100644 --- a/frontend/src/components/Tabs.tsx +++ b/frontend/src/components/Tabs.tsx @@ -19,14 +19,11 @@ const TabList = styled(Tab.List, { }); const TabButton = styled("button", { - ...tw` - px-3 py-2 border border-transparent rounded outline-none transition - focus:(ring border-indigo-500) ring-blue-600 ring-opacity-30 - `, + ...tw`rounded border border-transparent px-3 py-2 outline-none ring-blue-600 ring-opacity-30 transition focus:border-indigo-500 focus:ring`, variants: { active: { - true: tw`shadow bg-white border-gray-300 text-indigo-600 hover:(border-indigo-600 text-indigo-700)`, + true: tw`border-gray-300 bg-white text-indigo-600 shadow hover:border-indigo-600 hover:text-indigo-700`, false: tw`text-gray-700 hover:text-indigo-600`, }, }, diff --git a/frontend/src/components/Textarea.tsx b/frontend/src/components/Textarea.tsx index 4695c1c6f..e69f62d2d 100644 --- a/frontend/src/components/Textarea.tsx +++ b/frontend/src/components/Textarea.tsx @@ -1,13 +1,7 @@ import tw, { styled } from "twin.macro"; const styles = { - ...tw` - form-textarea block w-full rounded-md - border-gray-300 shadow-sm - transition - hover:border-blue-300 - focus:(border-blue-300 ring ring-blue-200 ring-opacity-50) - `, + ...tw`form-textarea block w-full rounded-md border-gray-300 shadow-sm transition hover:border-blue-300 focus:border-blue-300 focus:ring focus:ring-blue-200 focus:ring-opacity-50`, variants: { size: { @@ -20,9 +14,9 @@ const styles = { const Textarea = styled("textarea", styles); const Wrapper = styled("label", { ...styles, - ...tw`p-0 overflow-hidden`, + ...tw`overflow-hidden p-0`, }); -const Header = tw.header`px-3 py-2 flex items-center bg-gray-100 border-b border-gray-200`; +const Header = tw.header`flex items-center border-b border-gray-200 bg-gray-100 px-3 py-2`; export default Object.assign(Textarea, { Wrapper, diff --git a/frontend/src/components/Toast.tsx b/frontend/src/components/Toast.tsx index 4348c8ea7..82e959deb 100644 --- a/frontend/src/components/Toast.tsx +++ b/frontend/src/components/Toast.tsx @@ -11,7 +11,7 @@ import type { Toast as ToastObject } from "react-hot-toast"; const ButtonContainer = styled("div", tw`border-l border-gray-200`); const ToastContainer = styled("div", { - ...tw`flex w-full max-w-md bg-white rounded border shadow`, + ...tw`flex w-full max-w-md rounded border bg-white shadow`, variants: { type: { @@ -46,25 +46,19 @@ const Toast = ({ t, title, description, type = "notification" }: Props) => ( show={t.visible} appear enter={tw`duration-200 ease-out`} - enterFrom={tw`opacity-0 scale-95`} + enterFrom={tw`scale-95 opacity-0`} leave={tw`duration-150 ease-in`} - leaveTo={tw`opacity-0 scale-95`} + leaveTo={tw`scale-95 opacity-0`} > -
+

{title}

{description}

{/* have to add addition button here to create campaigns, or maybe it should go in a more obvious spot? */} @@ -253,7 +253,7 @@ const AdminContent = ({

) : ( campaign cover diff --git a/frontend/src/pages/admin/AdminLoading.tsx b/frontend/src/pages/admin/AdminLoading.tsx index 6894ba65e..158ca3adb 100644 --- a/frontend/src/pages/admin/AdminLoading.tsx +++ b/frontend/src/pages/admin/AdminLoading.tsx @@ -6,7 +6,7 @@ import CampaignLoading from "pages/dashboard/CampaignGrid/CampaignLoading"; const AdminLoading = () => (
-
+
{Array(4) .fill(null) .map((_, i) => ( @@ -31,7 +31,7 @@ const AdminLoading = () => (
-
+
{Array(5) .fill(null) .map((_, i) => ( diff --git a/frontend/src/pages/admin/review/finalise_candidates/index.tsx b/frontend/src/pages/admin/review/finalise_candidates/index.tsx index ca5740353..747b41613 100644 --- a/frontend/src/pages/admin/review/finalise_candidates/index.tsx +++ b/frontend/src/pages/admin/review/finalise_candidates/index.tsx @@ -32,7 +32,7 @@ import type { } from "types/api"; import type { DropFirst } from "types/util"; -const Icon = styled.span(tw`inline w-4 h-4`); +const Icon = styled.span(tw`inline h-4 w-4`); const tabIcons: { [status in ApplicationStatus]?: ReactNode } = { Success: , Rejected: , @@ -194,7 +194,7 @@ const FinaliseCandidates = () => {
@@ -205,17 +205,17 @@ const FinaliseCandidates = () => { - Preview + Preview
{renderEmail(id, name)}
) : (