From 45e6d06a7bdf0c1e42b313c65067864526ab3fbe Mon Sep 17 00:00:00 2001 From: Christopher Goh Date: Sun, 17 Dec 2023 14:13:39 +0800 Subject: [PATCH 01/10] Bootstrap Cargo --- .gitignore | 19 +++++++++++++++++++ backend/Cargo.lock | 7 +++++++ backend/Cargo.toml | 8 ++++++++ backend/src/main.rs | 3 +++ 4 files changed, 37 insertions(+) create mode 100644 backend/Cargo.lock create mode 100644 backend/Cargo.toml create mode 100644 backend/src/main.rs diff --git a/.gitignore b/.gitignore index 35643f877b..7f32ab018a 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,25 @@ infra/instance/proxy.env # Rest adapted from https://www.gitignore.io/api/vim,node,linux,macos,emacs,windows,ansible,database,webstorm,visualstudiocode +### Rust ### +# Adapted from https://github.com/github/gitignore/blob/main/Rust.gitignore + +# Generated by Cargo +# will have compiled files and executables +debug/ +target/ + +# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries +# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html +# Cargo.lock + +# These are backup files generated by rustfmt +**/*.rs.bk + +# MSVC Windows builds of rustc generate these, which store debugging information +*.pdb + + ### Ansible ### *.retry diff --git a/backend/Cargo.lock b/backend/Cargo.lock new file mode 100644 index 0000000000..3b3d789eca --- /dev/null +++ b/backend/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "backend" +version = "0.1.0" diff --git a/backend/Cargo.toml b/backend/Cargo.toml new file mode 100644 index 0000000000..f781829d28 --- /dev/null +++ b/backend/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "backend" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/backend/src/main.rs b/backend/src/main.rs new file mode 100644 index 0000000000..e7a11a969c --- /dev/null +++ b/backend/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} From d96ec05f6e2b90b637f4d2694f04d6acd9932068 Mon Sep 17 00:00:00 2001 From: Christopher Goh Date: Sun, 17 Dec 2023 14:34:24 +0800 Subject: [PATCH 02/10] Bootstrap Cargo more --- backend/Cargo.lock | 2 +- backend/Cargo.toml | 17 +++++++++++++---- backend/clippy.toml | 5 +++++ backend/crates/nusmods-api/Cargo.toml | 8 ++++++++ backend/{ => crates/nusmods-api}/src/main.rs | 0 backend/rust-toolchain.toml | 3 +++ 6 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 backend/clippy.toml create mode 100644 backend/crates/nusmods-api/Cargo.toml rename backend/{ => crates/nusmods-api}/src/main.rs (100%) create mode 100644 backend/rust-toolchain.toml diff --git a/backend/Cargo.lock b/backend/Cargo.lock index 3b3d789eca..a01b085c4d 100644 --- a/backend/Cargo.lock +++ b/backend/Cargo.lock @@ -3,5 +3,5 @@ version = 3 [[package]] -name = "backend" +name = "nusmods-api" version = "0.1.0" diff --git a/backend/Cargo.toml b/backend/Cargo.toml index f781829d28..26d6b2b51b 100644 --- a/backend/Cargo.toml +++ b/backend/Cargo.toml @@ -1,8 +1,17 @@ -[package] -name = "backend" +[workspace] +members = [ + "crates/*", +] +resolver = "2" + +[workspace.package] version = "0.1.0" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[profile.aggressive] +inherits = "release" +lto = true +panic = 'abort' +codegen-units = 1 -[dependencies] +[workspace.dependencies] diff --git a/backend/clippy.toml b/backend/clippy.toml new file mode 100644 index 0000000000..a37ad9b46d --- /dev/null +++ b/backend/clippy.toml @@ -0,0 +1,5 @@ +allow-unwrap-in-tests = true + +# Use ahash::HashMap and ahash::HashSet instead because they are much faster than +# the default hashing algo used by Rust +disallowed-types = ["std::collections::HashMap", "std::collections::HashSet"] \ No newline at end of file diff --git a/backend/crates/nusmods-api/Cargo.toml b/backend/crates/nusmods-api/Cargo.toml new file mode 100644 index 0000000000..e0380048c1 --- /dev/null +++ b/backend/crates/nusmods-api/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "nusmods-api" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/backend/src/main.rs b/backend/crates/nusmods-api/src/main.rs similarity index 100% rename from backend/src/main.rs rename to backend/crates/nusmods-api/src/main.rs diff --git a/backend/rust-toolchain.toml b/backend/rust-toolchain.toml new file mode 100644 index 0000000000..a3fcac87f7 --- /dev/null +++ b/backend/rust-toolchain.toml @@ -0,0 +1,3 @@ +[toolchain] +channel = "1.74" +profile = "default" From 6021081155a4b63fe9e1be1d8da82b7eb40349f6 Mon Sep 17 00:00:00 2001 From: Christopher Goh Date: Sun, 17 Dec 2023 14:51:05 +0800 Subject: [PATCH 03/10] Add deps --- backend/Cargo.lock | 1060 +++++++++++++++++++++++++ backend/Cargo.toml | 7 + backend/clippy.toml | 2 +- backend/crates/nusmods-api/Cargo.toml | 11 +- 4 files changed, 1077 insertions(+), 3 deletions(-) diff --git a/backend/Cargo.lock b/backend/Cargo.lock index a01b085c4d..ac798689f5 100644 --- a/backend/Cargo.lock +++ b/backend/Cargo.lock @@ -2,6 +2,1066 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "ahash" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" +dependencies = [ + "cfg-if", + "getrandom", + "once_cell", + "serde", + "version_check", + "zerocopy", +] + +[[package]] +name = "anstream" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" + +[[package]] +name = "anstyle-parse" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + +[[package]] +name = "anyhow" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" + +[[package]] +name = "async-trait" +version = "0.1.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "axum" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "202651474fe73c62d9e0a56c6133f7a0ff1dc1c8cf7a5b03381af2a26553ac9d" +dependencies = [ + "async-trait", + "axum-core", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77cb22c689c44d4c07b0ab44ebc25d69d8ae601a2f28fb8d672d344178fa17aa" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "rustversion", + "sync_wrapper", + "tower-layer", + "tower-service", +] + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "4.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures-channel" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" + +[[package]] +name = "futures-sink" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" + +[[package]] +name = "futures-task" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" + +[[package]] +name = "futures-util" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "pin-utils", +] + +[[package]] +name = "getrandom" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "h2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d308f63daf4181410c242d34c11f928dcb3aa105852019e043c9d1f4e4368a" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" + +[[package]] +name = "http" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cb79eb393015dadd30fc252023adb0b2400a0caee0fa2a077e6e21a551e840" +dependencies = [ + "bytes", + "futures-util", + "http", + "http-body", + "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.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "403f9214f3e703236b221f1a9cd88ec8b4adfa5296de01ab96216361f4692f56" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "hyper-util" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ca339002caeb0d159cc6e023dff48e199f081e42fa039895c7c6f38b37f2e9d" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "pin-project-lite", + "socket2", + "tokio", + "tower", + "tower-service", + "tracing", +] + +[[package]] +name = "indexmap" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + +[[package]] +name = "libc" +version = "0.2.151" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + +[[package]] +name = "memchr" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + [[package]] name = "nusmods-api" version = "0.1.0" +dependencies = [ + "ahash", + "anyhow", + "axum", + "clap", + "serde", + "thiserror", + "tokio", +] + +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[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.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.48.5", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "proc-macro2" +version = "1.0.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "ryu" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "serde" +version = "1.0.193" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.193" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_path_to_error" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4beec8bce849d58d06238cb50db2e1c417cfeafa4c63f692b15c82b7c80f8335" +dependencies = [ + "itoa", + "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 = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" + +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "2.0.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "thiserror" +version = "1.0.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f11c217e1416d6f036b870f14e0413d480dbf28edbee1f877abaf0206af43bb7" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01742297787513b79cf8e29d1056ede1313e2420b7b3b15d0a768b4921f549df" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio" +version = "1.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d45b238a16291a4e1584e61820b8ae57d696cc5015c459c229ccc6990cc1c" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[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.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "log", + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + +[[package]] +name = "zerocopy" +version = "0.7.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c4061bedbb353041c12f413700357bec76df2c7e2ca8e4df8bac24c6bf68e3d" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3c129550b3e6de3fd0ba67ba5c81818f9805e58b8d7fee80a3a59d2c9fc601a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/backend/Cargo.toml b/backend/Cargo.toml index 26d6b2b51b..9b13f49f6f 100644 --- a/backend/Cargo.toml +++ b/backend/Cargo.toml @@ -15,3 +15,10 @@ panic = 'abort' codegen-units = 1 [workspace.dependencies] +ahash = { version = "0.8.6", features = ["serde"] } +anyhow = "1.0.75" +axum = "0.7.2" +clap ={ version = "4.4.11", features = ["derive", "env"] } +serde = { version = "1.0.193", features = ["derive", "rc"]} +thiserror = "1.0.51" +tokio = { version = "1.35.0", features = ["full"] } diff --git a/backend/clippy.toml b/backend/clippy.toml index a37ad9b46d..07729009a6 100644 --- a/backend/clippy.toml +++ b/backend/clippy.toml @@ -2,4 +2,4 @@ allow-unwrap-in-tests = true # Use ahash::HashMap and ahash::HashSet instead because they are much faster than # the default hashing algo used by Rust -disallowed-types = ["std::collections::HashMap", "std::collections::HashSet"] \ No newline at end of file +disallowed-types = ["std::collections::HashMap", "std::collections::HashSet"] diff --git a/backend/crates/nusmods-api/Cargo.toml b/backend/crates/nusmods-api/Cargo.toml index e0380048c1..179120f210 100644 --- a/backend/crates/nusmods-api/Cargo.toml +++ b/backend/crates/nusmods-api/Cargo.toml @@ -1,8 +1,15 @@ [package] name = "nusmods-api" -version = "0.1.0" -edition = "2021" +version.workspace = true +version.edition = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +ahash.workspace = true +anyhow.workspace = true +axum.workspace = true +clap.workspace = true +serde.workspace = true +thiserror.workspace = true +tokio.workspace = true From 214637dd38b90713d6b7203841e41394728c40ec Mon Sep 17 00:00:00 2001 From: Christopher Goh Date: Sun, 17 Dec 2023 15:08:54 +0800 Subject: [PATCH 04/10] Add barebones HTTP server --- backend/Cargo.lock | 96 +++++++++++++++++++++++ backend/Cargo.toml | 1 + backend/crates/nusmods-api/Cargo.toml | 3 +- backend/crates/nusmods-api/src/bin/api.rs | 57 ++++++++++++++ backend/crates/nusmods-api/src/main.rs | 3 - 5 files changed, 156 insertions(+), 4 deletions(-) create mode 100644 backend/crates/nusmods-api/src/bin/api.rs delete mode 100644 backend/crates/nusmods-api/src/main.rs diff --git a/backend/Cargo.lock b/backend/Cargo.lock index ac798689f5..7f61b7a504 100644 --- a/backend/Cargo.lock +++ b/backend/Cargo.lock @@ -458,6 +458,12 @@ version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +[[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.151" @@ -518,6 +524,16 @@ dependencies = [ "windows-sys 0.48.0", ] +[[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_cpus" version = "1.16.0" @@ -539,6 +555,7 @@ dependencies = [ "serde", "thiserror", "tokio", + "tracing-subscriber", ] [[package]] @@ -556,6 +573,12 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[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" @@ -721,6 +744,15 @@ dependencies = [ "serde", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "signal-hook-registry" version = "1.4.1" @@ -798,6 +830,16 @@ dependencies = [ "syn", ] +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if", + "once_cell", +] + [[package]] name = "tokio" version = "1.35.0" @@ -888,6 +930,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "nu-ansi-term", + "sharded-slab", + "smallvec", + "thread_local", + "tracing-core", + "tracing-log", ] [[package]] @@ -902,6 +970,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "version_check" version = "0.9.4" @@ -914,6 +988,28 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[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 = "windows-sys" version = "0.48.0" diff --git a/backend/Cargo.toml b/backend/Cargo.toml index 9b13f49f6f..d52a0a6b55 100644 --- a/backend/Cargo.toml +++ b/backend/Cargo.toml @@ -22,3 +22,4 @@ clap ={ version = "4.4.11", features = ["derive", "env"] } serde = { version = "1.0.193", features = ["derive", "rc"]} thiserror = "1.0.51" tokio = { version = "1.35.0", features = ["full"] } +tracing-subscriber = "0.3.18" \ No newline at end of file diff --git a/backend/crates/nusmods-api/Cargo.toml b/backend/crates/nusmods-api/Cargo.toml index 179120f210..69fd464dce 100644 --- a/backend/crates/nusmods-api/Cargo.toml +++ b/backend/crates/nusmods-api/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "nusmods-api" version.workspace = true -version.edition = true +edition.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -13,3 +13,4 @@ clap.workspace = true serde.workspace = true thiserror.workspace = true tokio.workspace = true +tracing-subscriber.workspace = true diff --git a/backend/crates/nusmods-api/src/bin/api.rs b/backend/crates/nusmods-api/src/bin/api.rs new file mode 100644 index 0000000000..1bf7e12728 --- /dev/null +++ b/backend/crates/nusmods-api/src/bin/api.rs @@ -0,0 +1,57 @@ +use axum::{ + routing::{get, post}, + http::StatusCode, + Json, Router, +}; +use serde::{Deserialize, Serialize}; + +#[tokio::main] +async fn main() { + // initialize tracing + tracing_subscriber::fmt::init(); + + // build our application with a route + let app = Router::new() + // `GET /` goes to `root` + .route("/", get(root)) + // `POST /users` goes to `create_user` + .route("/users", post(create_user)); + + // run our app with hyper, listening globally on port 3000 + let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); + axum::serve(listener, app).await.unwrap(); +} + +// basic handler that responds with a static string +async fn root() -> &'static str { + "Hello, World!" +} + +async fn create_user( + // this argument tells axum to parse the request body + // as JSON into a `CreateUser` type + Json(payload): Json, +) -> (StatusCode, Json) { + // insert your application logic here + let user = User { + id: 1337, + username: payload.username, + }; + + // this will be converted into a JSON response + // with a status code of `201 Created` + (StatusCode::CREATED, Json(user)) +} + +// the input to our `create_user` handler +#[derive(Deserialize)] +struct CreateUser { + username: String, +} + +// the output to our `create_user` handler +#[derive(Serialize)] +struct User { + id: u64, + username: String, +} \ No newline at end of file diff --git a/backend/crates/nusmods-api/src/main.rs b/backend/crates/nusmods-api/src/main.rs deleted file mode 100644 index e7a11a969c..0000000000 --- a/backend/crates/nusmods-api/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - println!("Hello, world!"); -} From eeeb16537e3e406b421d7ce67bcdf07c7a43bd25 Mon Sep 17 00:00:00 2001 From: Christopher Goh Date: Sun, 17 Dec 2023 19:49:20 +0800 Subject: [PATCH 05/10] Add skeleton of API --- backend/Cargo.lock | 1 + backend/Cargo.toml | 12 ++--- backend/README.md | 9 ++++ backend/auth/FederationMetadata.xml | 1 + backend/auth/sp.xml | 21 ++++++++ backend/crates/nusmods-api/Cargo.toml | 1 + backend/crates/nusmods-api/src/auth.rs | 10 ++++ backend/crates/nusmods-api/src/bin/api.rs | 58 +++++------------------ backend/crates/nusmods-api/src/lib.rs | 4 ++ backend/crates/nusmods-api/src/reviews.rs | 10 ++++ 10 files changed, 76 insertions(+), 51 deletions(-) create mode 100644 backend/README.md create mode 100644 backend/auth/FederationMetadata.xml create mode 100644 backend/auth/sp.xml create mode 100644 backend/crates/nusmods-api/src/auth.rs create mode 100644 backend/crates/nusmods-api/src/lib.rs create mode 100644 backend/crates/nusmods-api/src/reviews.rs diff --git a/backend/Cargo.lock b/backend/Cargo.lock index 7f61b7a504..b43b88af8e 100644 --- a/backend/Cargo.lock +++ b/backend/Cargo.lock @@ -555,6 +555,7 @@ dependencies = [ "serde", "thiserror", "tokio", + "tower", "tracing-subscriber", ] diff --git a/backend/Cargo.toml b/backend/Cargo.toml index d52a0a6b55..eaa7c1283a 100644 --- a/backend/Cargo.toml +++ b/backend/Cargo.toml @@ -1,7 +1,5 @@ [workspace] -members = [ - "crates/*", -] +members = ["crates/*"] resolver = "2" [workspace.package] @@ -18,8 +16,10 @@ codegen-units = 1 ahash = { version = "0.8.6", features = ["serde"] } anyhow = "1.0.75" axum = "0.7.2" -clap ={ version = "4.4.11", features = ["derive", "env"] } -serde = { version = "1.0.193", features = ["derive", "rc"]} +clap = { version = "4.4.11", features = ["derive", "env"] } +samael = { version = "0.0.14", features = ["xmlsec"] } +serde = { version = "1.0.193", features = ["derive", "rc"] } thiserror = "1.0.51" +tower = "0.4.13" tokio = { version = "1.35.0", features = ["full"] } -tracing-subscriber = "0.3.18" \ No newline at end of file +tracing-subscriber = "0.3.18" diff --git a/backend/README.md b/backend/README.md new file mode 100644 index 0000000000..8ce39df4ca --- /dev/null +++ b/backend/README.md @@ -0,0 +1,9 @@ +# Set-up + +(If we are reimplementing SAML in Rust, with the `samael` crate) +Build deps required for SAML auth: + +```bash +$ sudo apt-get update +$ sudo apt-get install pkg-config libxml2-dev libclang-dev openssl libssl-dev xmlsec1 libtool libxml2 libxmlsec1-dev +``` diff --git a/backend/auth/FederationMetadata.xml b/backend/auth/FederationMetadata.xml new file mode 100644 index 0000000000..7a27f5de7d --- /dev/null +++ b/backend/auth/FederationMetadata.xml @@ -0,0 +1 @@ +EMBTkCa4qOswlQ4vwNt+G5Em8Eww/HV8mpbPyGWjt6I=HdmYWtNTCOacUxZonZbbeyG61EFMGYXLw/IldX7F7lwpQQRxqlcTIHayyU2ZJBnmqoKxKElzXIDjkbzBvPi66FXW7rI2oqM4n9Nz7DmQrdvmSKW0haf4vwavBmEO4qktCfwpgwb4vIWfmJOeHnNMHQHV2QkgYrTw1wES6YUY6ChWWhG1vEhPyQJ8VlUvs3WAuHExfl0Nbn5h+z9iSGxzcLSr/wZT6dJaoGcU5CX//UAB3ozMfOvNSLvp44QraG+keTVBKsiuNHFy7CkSLwrLE+lcWTSyc6EcXVRvq8iNYfBA8NGM/6EQMQszRpXzmEMZsWfydRm/L68fvAhKlr5tFA==MIIC2jCCAcKgAwIBAgIQZGfcLJOybI1IfVkwLAsjvzANBgkqhkiG9w0BAQsFADApMScwJQYDVQQDEx5BREZTIFNpZ25pbmcgLSB2YWZzLm51cy5lZHUuc2cwHhcNMjEwNTA0MTUwNTIyWhcNMjQwNTAzMTUwNTIyWjApMScwJQYDVQQDEx5BREZTIFNpZ25pbmcgLSB2YWZzLm51cy5lZHUuc2cwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCQ4NkCXYgBUGWJCsMc9y1/zSijXP8teRE4qBksInkUAmklE6I3kb/39HrO6evOWYXiUBHZS5jCiZlRHeYkp/2dli9N2nn3b6K34fLha6nqYtx9BBWZK5oKu6xQJMIlMdsm1PlMWGc+XvMmZOvPpSzocijC++DfjGAL2V1bLPG2kI6Q3NxR3DiYqTosdvksuFtE/hIYZYhEpZMPu84a3bn0d4ImDDBQV9xq3qqi8FNeuYng/Fz+1rXM7Oh7FXE7zgQXmAPxClsqWAkWpaYvOsAJUfeovwV+YKP9/KaxVNZSXSHCL3eGcdUJb1xGo/u/dI6iLc/RmcHitu5jDMh2iz/PAgMBAAEwDQYJKoZIhvcNAQELBQADggEBADz99ae5b28QT057tjue+hnS7G6/8DNC/5lyXRHoW1NnIzr4kOvJTNlm5fqstTl6CdETTwfjmE25ThH6vRKzMRDEBPAsIDjMMMnGbybJNVrqIvuskwIfs0agO2jXiAPg9LPJjC3bH6KnnDBMnXVNP/aMAT2+KgiJWnGElF/LMYcpn2thPV+tEnVr/2+pYMdTH75LwfqFgSNHT8HUyZ3Cb9W/Z66er3fa2HolHHzkDpoiRMXM34Gsx4ULSRFufVewgi8SRnd1+vDcMav0qGtH1ajsAJ5oqJ+a7Kpf7GDabPSYBbHJsTAKK3P4LNVG9AVskBOKRQl9uBAlIA07MPE/E1U=MIIC4DCCAcigAwIBAgIQXm7+axsX6IRO+Aj+zpzU3DANBgkqhkiG9w0BAQsFADAsMSowKAYDVQQDEyFBREZTIEVuY3J5cHRpb24gLSB2YWZzLm51cy5lZHUuc2cwHhcNMjEwNTA0MTUwNTI3WhcNMjQwNTAzMTUwNTI3WjAsMSowKAYDVQQDEyFBREZTIEVuY3J5cHRpb24gLSB2YWZzLm51cy5lZHUuc2cwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCcqQ7nnhRAJpolHmE5ZvhtnlsNNcBrFVqxwX3ESJdHfy2gV0t5UEWyMyVHaHSc1TPitTfu1iuHFZcfqz+IQnbc/PsLf/KTJsqDmyCk/JmftacIj5BLdIp4ptI2gJXPiiPcIdCVf9vd4RDaa8huLlcSSGY4itRjdPvk/lOiI/J7jeUEnHSiPveMwxJD+EHFqzImbj6acARO7t8QWxPcp1glPxY10PO94tXHHy2CuWeA3CKj7tg2J+NTb2RFWnkOnsUp1UtUJw7E60jmLoXo+bVCjes95KNPXdkVxdtRmkHbSdo2vKl1DdiMM6jt5lvapox8XRzWsX4/YaQZtgZa9FF3AgMBAAEwDQYJKoZIhvcNAQELBQADggEBAIs5nI0GNJ8s/6yXNjw+ZPkDxv8s+zEZ3NJSZepdASJy2aIEx/EA/SsDOh2lk3aRjYGJhUMmGRPe/OPqelYq1ed5gnDepjTpkXiQ0vgaeelbDPJZ8y/em7l8JjxQN4t7psSes2j8RZZCIQxmBvxg6vv/Dv6nR1eyVPo6VwW80rN4XRIEn1QbO8loL0wmf06lKRp7l8TJmnZPHfsBvkIcq2AYv/ktztHqp6P6AjEVF5dHnJZ5aotz3xudRA14ufbGTRpuAcTTbbH7ZIi99XuGs83F8oW0McecmSMarTiI9KFWQU7p3Y8uFDvcQgF9xFdqK33wvNsnOoqmM3G+MEFBGks=E-Mail AddressThe e-mail address of the userGiven NameThe given name of the userNameThe unique name of the userUPNThe user principal name (UPN) of the userCommon NameThe common name of the userAD FS 1.x E-Mail AddressThe e-mail address of the user when interoperating with AD FS 1.1 or AD FS 1.0GroupA group that the user is a member ofAD FS 1.x UPNThe UPN of the user when interoperating with AD FS 1.1 or AD FS 1.0RoleA role that the user hasSurnameThe surname of the userPPIDThe private identifier of the userName IDThe SAML name identifier of the userAuthentication time stampUsed to display the time and date that the user was authenticatedAuthentication methodThe method used to authenticate the userDeny only group SIDThe deny-only group SID of the userDeny only primary SIDThe deny-only primary SID of the userDeny only primary group SIDThe deny-only primary group SID of the userGroup SIDThe group SID of the userPrimary group SIDThe primary group SID of the userPrimary SIDThe primary SID of the userWindows account nameThe domain account name of the user in the form of domain\userIs Registered UserUser is registered to use this deviceDevice IdentifierIdentifier of the deviceDevice Registration IdentifierIdentifier for Device RegistrationDevice Registration DisplayNameDisplay name of Device RegistrationDevice OS typeOS type of the deviceDevice OS VersionOS version of the deviceIs Managed DeviceDevice is managed by a management serviceForwarded Client IPIP address of the userClient ApplicationType of the Client ApplicationClient User AgentDevice type the client is using to access the applicationClient IPIP address of the clientEndpoint PathAbsolute Endpoint path which can be used to determine active versus passive clientsProxyDNS name of the federation server proxy that passed the requestApplication IdentifierIdentifier for the Relying PartyApplication policiesApplication policies of the certificateAuthority Key IdentifierThe Authority Key Identifier extension of the certificate that signed an issued certificateBasic ConstraintOne of the basic constraints of the certificateEnhanced Key UsageDescribes one of the enhanced key usages of the certificateIssuerThe name of the certificate authority that issued the X.509 certificateIssuer NameThe distinguished name of the certificate issuerKey UsageOne of the key usages of the certificateNot AfterDate in local time after which a certificate is no longer validNot BeforeThe date in local time on which a certificate becomes validCertificate PoliciesThe policies under which the certificate has been issuedPublic KeyPublic Key of the certificateCertificate Raw DataThe raw data of the certificateSubject Alternative NameOne of the alternative names of the certificateSerial NumberThe serial number of a certificateSignature AlgorithmThe algorithm used to create the signature of a certificateSubjectThe subject from the certificateSubject Key IdentifierDescribes the subject key identifier of the certificateSubject NameThe subject distinguished name from a certificateV2 Template NameThe name of the version 2 certificate template used when issuing or renewing a certificate. The extension is Microsoft specific.V1 Template NameThe name of the version 1 certificate template used when issuing or renewing a certificate. The extension is Microsoft specific.ThumbprintThumbprint of the certificateX.509 VersionThe X.509 format version of a certificateInside Corporate NetworkUsed to indicate if a request originated inside corporate networkPassword Expiration TimeUsed to display the time when the password expiresPassword Expiration DaysUsed to display the number of days to password expiryUpdate Password URLUsed to display the web address of update password serviceAuthentication Methods ReferencesUsed to indicate all authentication methods used to authenticate the userClient Request IDIdentifier for a user sessionAlternate Login IDAlternate login ID of the userdisplayNamemailmail (inetOrgPerson)SamAccountNameAD SamAccountName (userid)
https://vafs.nus.edu.sg/adfs/services/trust/2005/issuedtokenmixedasymmetricbasic256
https://vafs.nus.edu.sg/adfs/services/trust/2005/issuedtokenmixedsymmetricbasic256
https://vafs.nus.edu.sg/adfs/services/trust/13/issuedtokenmixedasymmetricbasic256
https://vafs.nus.edu.sg/adfs/services/trust/13/issuedtokenmixedsymmetricbasic256
https://vafs.nus.edu.sg/adfs/ls/
https://vafs.nus.edu.sg/adfs/services/trust
https://vafs.nus.edu.sg/adfs/services/trust/2005/issuedtokenmixedasymmetricbasic256
https://vafs.nus.edu.sg/adfs/ls/
MIIC2jCCAcKgAwIBAgIQZGfcLJOybI1IfVkwLAsjvzANBgkqhkiG9w0BAQsFADApMScwJQYDVQQDEx5BREZTIFNpZ25pbmcgLSB2YWZzLm51cy5lZHUuc2cwHhcNMjEwNTA0MTUwNTIyWhcNMjQwNTAzMTUwNTIyWjApMScwJQYDVQQDEx5BREZTIFNpZ25pbmcgLSB2YWZzLm51cy5lZHUuc2cwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCQ4NkCXYgBUGWJCsMc9y1/zSijXP8teRE4qBksInkUAmklE6I3kb/39HrO6evOWYXiUBHZS5jCiZlRHeYkp/2dli9N2nn3b6K34fLha6nqYtx9BBWZK5oKu6xQJMIlMdsm1PlMWGc+XvMmZOvPpSzocijC++DfjGAL2V1bLPG2kI6Q3NxR3DiYqTosdvksuFtE/hIYZYhEpZMPu84a3bn0d4ImDDBQV9xq3qqi8FNeuYng/Fz+1rXM7Oh7FXE7zgQXmAPxClsqWAkWpaYvOsAJUfeovwV+YKP9/KaxVNZSXSHCL3eGcdUJb1xGo/u/dI6iLc/RmcHitu5jDMh2iz/PAgMBAAEwDQYJKoZIhvcNAQELBQADggEBADz99ae5b28QT057tjue+hnS7G6/8DNC/5lyXRHoW1NnIzr4kOvJTNlm5fqstTl6CdETTwfjmE25ThH6vRKzMRDEBPAsIDjMMMnGbybJNVrqIvuskwIfs0agO2jXiAPg9LPJjC3bH6KnnDBMnXVNP/aMAT2+KgiJWnGElF/LMYcpn2thPV+tEnVr/2+pYMdTH75LwfqFgSNHT8HUyZ3Cb9W/Z66er3fa2HolHHzkDpoiRMXM34Gsx4ULSRFufVewgi8SRnd1+vDcMav0qGtH1ajsAJ5oqJ+a7Kpf7GDabPSYBbHJsTAKK3P4LNVG9AVskBOKRQl9uBAlIA07MPE/E1U=E-Mail AddressThe e-mail address of the userGiven NameThe given name of the userNameThe unique name of the userUPNThe user principal name (UPN) of the userCommon NameThe common name of the userAD FS 1.x E-Mail AddressThe e-mail address of the user when interoperating with AD FS 1.1 or AD FS 1.0GroupA group that the user is a member ofAD FS 1.x UPNThe UPN of the user when interoperating with AD FS 1.1 or AD FS 1.0RoleA role that the user hasSurnameThe surname of the userPPIDThe private identifier of the userName IDThe SAML name identifier of the userAuthentication time stampUsed to display the time and date that the user was authenticatedAuthentication methodThe method used to authenticate the userDeny only group SIDThe deny-only group SID of the userDeny only primary SIDThe deny-only primary SID of the userDeny only primary group SIDThe deny-only primary group SID of the userGroup SIDThe group SID of the userPrimary group SIDThe primary group SID of the userPrimary SIDThe primary SID of the userWindows account nameThe domain account name of the user in the form of domain\userIs Registered UserUser is registered to use this deviceDevice IdentifierIdentifier of the deviceDevice Registration IdentifierIdentifier for Device RegistrationDevice Registration DisplayNameDisplay name of Device RegistrationDevice OS typeOS type of the deviceDevice OS VersionOS version of the deviceIs Managed DeviceDevice is managed by a management serviceForwarded Client IPIP address of the userClient ApplicationType of the Client ApplicationClient User AgentDevice type the client is using to access the applicationClient IPIP address of the clientEndpoint PathAbsolute Endpoint path which can be used to determine active versus passive clientsProxyDNS name of the federation server proxy that passed the requestApplication IdentifierIdentifier for the Relying PartyApplication policiesApplication policies of the certificateAuthority Key IdentifierThe Authority Key Identifier extension of the certificate that signed an issued certificateBasic ConstraintOne of the basic constraints of the certificateEnhanced Key UsageDescribes one of the enhanced key usages of the certificateIssuerThe name of the certificate authority that issued the X.509 certificateIssuer NameThe distinguished name of the certificate issuerKey UsageOne of the key usages of the certificateNot AfterDate in local time after which a certificate is no longer validNot BeforeThe date in local time on which a certificate becomes validCertificate PoliciesThe policies under which the certificate has been issuedPublic KeyPublic Key of the certificateCertificate Raw DataThe raw data of the certificateSubject Alternative NameOne of the alternative names of the certificateSerial NumberThe serial number of a certificateSignature AlgorithmThe algorithm used to create the signature of a certificateSubjectThe subject from the certificateSubject Key IdentifierDescribes the subject key identifier of the certificateSubject NameThe subject distinguished name from a certificateV2 Template NameThe name of the version 2 certificate template used when issuing or renewing a certificate. The extension is Microsoft specific.V1 Template NameThe name of the version 1 certificate template used when issuing or renewing a certificate. The extension is Microsoft specific.ThumbprintThumbprint of the certificateX.509 VersionThe X.509 format version of a certificateInside Corporate NetworkUsed to indicate if a request originated inside corporate networkPassword Expiration TimeUsed to display the time when the password expiresPassword Expiration DaysUsed to display the number of days to password expiryUpdate Password URLUsed to display the web address of update password serviceAuthentication Methods ReferencesUsed to indicate all authentication methods used to authenticate the userClient Request IDIdentifier for a user sessionAlternate Login IDAlternate login ID of the userdisplayNamemailmail (inetOrgPerson)SamAccountNameAD SamAccountName (userid)eduPersonTargetedIDeduPersonTargetedIDuidAD UID attributeeduPersonPrincipalNameeduPersonAffiliationProxy AddressesmemberOfcountry
https://vafs.nus.edu.sg/adfs/services/trust/2005/certificatemixed
https://vafs.nus.edu.sg/adfs/services/trust/mex
https://vafs.nus.edu.sg/adfs/ls/
MIIC4DCCAcigAwIBAgIQXm7+axsX6IRO+Aj+zpzU3DANBgkqhkiG9w0BAQsFADAsMSowKAYDVQQDEyFBREZTIEVuY3J5cHRpb24gLSB2YWZzLm51cy5lZHUuc2cwHhcNMjEwNTA0MTUwNTI3WhcNMjQwNTAzMTUwNTI3WjAsMSowKAYDVQQDEyFBREZTIEVuY3J5cHRpb24gLSB2YWZzLm51cy5lZHUuc2cwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCcqQ7nnhRAJpolHmE5ZvhtnlsNNcBrFVqxwX3ESJdHfy2gV0t5UEWyMyVHaHSc1TPitTfu1iuHFZcfqz+IQnbc/PsLf/KTJsqDmyCk/JmftacIj5BLdIp4ptI2gJXPiiPcIdCVf9vd4RDaa8huLlcSSGY4itRjdPvk/lOiI/J7jeUEnHSiPveMwxJD+EHFqzImbj6acARO7t8QWxPcp1glPxY10PO94tXHHy2CuWeA3CKj7tg2J+NTb2RFWnkOnsUp1UtUJw7E60jmLoXo+bVCjes95KNPXdkVxdtRmkHbSdo2vKl1DdiMM6jt5lvapox8XRzWsX4/YaQZtgZa9FF3AgMBAAEwDQYJKoZIhvcNAQELBQADggEBAIs5nI0GNJ8s/6yXNjw+ZPkDxv8s+zEZ3NJSZepdASJy2aIEx/EA/SsDOh2lk3aRjYGJhUMmGRPe/OPqelYq1ed5gnDepjTpkXiQ0vgaeelbDPJZ8y/em7l8JjxQN4t7psSes2j8RZZCIQxmBvxg6vv/Dv6nR1eyVPo6VwW80rN4XRIEn1QbO8loL0wmf06lKRp7l8TJmnZPHfsBvkIcq2AYv/ktztHqp6P6AjEVF5dHnJZ5aotz3xudRA14ufbGTRpuAcTTbbH7ZIi99XuGs83F8oW0McecmSMarTiI9KFWQU7p3Y8uFDvcQgF9xFdqK33wvNsnOoqmM3G+MEFBGks=MIIC2jCCAcKgAwIBAgIQZGfcLJOybI1IfVkwLAsjvzANBgkqhkiG9w0BAQsFADApMScwJQYDVQQDEx5BREZTIFNpZ25pbmcgLSB2YWZzLm51cy5lZHUuc2cwHhcNMjEwNTA0MTUwNTIyWhcNMjQwNTAzMTUwNTIyWjApMScwJQYDVQQDEx5BREZTIFNpZ25pbmcgLSB2YWZzLm51cy5lZHUuc2cwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCQ4NkCXYgBUGWJCsMc9y1/zSijXP8teRE4qBksInkUAmklE6I3kb/39HrO6evOWYXiUBHZS5jCiZlRHeYkp/2dli9N2nn3b6K34fLha6nqYtx9BBWZK5oKu6xQJMIlMdsm1PlMWGc+XvMmZOvPpSzocijC++DfjGAL2V1bLPG2kI6Q3NxR3DiYqTosdvksuFtE/hIYZYhEpZMPu84a3bn0d4ImDDBQV9xq3qqi8FNeuYng/Fz+1rXM7Oh7FXE7zgQXmAPxClsqWAkWpaYvOsAJUfeovwV+YKP9/KaxVNZSXSHCL3eGcdUJb1xGo/u/dI6iLc/RmcHitu5jDMh2iz/PAgMBAAEwDQYJKoZIhvcNAQELBQADggEBADz99ae5b28QT057tjue+hnS7G6/8DNC/5lyXRHoW1NnIzr4kOvJTNlm5fqstTl6CdETTwfjmE25ThH6vRKzMRDEBPAsIDjMMMnGbybJNVrqIvuskwIfs0agO2jXiAPg9LPJjC3bH6KnnDBMnXVNP/aMAT2+KgiJWnGElF/LMYcpn2thPV+tEnVr/2+pYMdTH75LwfqFgSNHT8HUyZ3Cb9W/Z66er3fa2HolHHzkDpoiRMXM34Gsx4ULSRFufVewgi8SRnd1+vDcMav0qGtH1ajsAJ5oqJ+a7Kpf7GDabPSYBbHJsTAKK3P4LNVG9AVskBOKRQl9uBAlIA07MPE/E1U=urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddressurn:oasis:names:tc:SAML:2.0:nameid-format:persistenturn:oasis:names:tc:SAML:2.0:nameid-format:transientMIIC4DCCAcigAwIBAgIQXm7+axsX6IRO+Aj+zpzU3DANBgkqhkiG9w0BAQsFADAsMSowKAYDVQQDEyFBREZTIEVuY3J5cHRpb24gLSB2YWZzLm51cy5lZHUuc2cwHhcNMjEwNTA0MTUwNTI3WhcNMjQwNTAzMTUwNTI3WjAsMSowKAYDVQQDEyFBREZTIEVuY3J5cHRpb24gLSB2YWZzLm51cy5lZHUuc2cwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCcqQ7nnhRAJpolHmE5ZvhtnlsNNcBrFVqxwX3ESJdHfy2gV0t5UEWyMyVHaHSc1TPitTfu1iuHFZcfqz+IQnbc/PsLf/KTJsqDmyCk/JmftacIj5BLdIp4ptI2gJXPiiPcIdCVf9vd4RDaa8huLlcSSGY4itRjdPvk/lOiI/J7jeUEnHSiPveMwxJD+EHFqzImbj6acARO7t8QWxPcp1glPxY10PO94tXHHy2CuWeA3CKj7tg2J+NTb2RFWnkOnsUp1UtUJw7E60jmLoXo+bVCjes95KNPXdkVxdtRmkHbSdo2vKl1DdiMM6jt5lvapox8XRzWsX4/YaQZtgZa9FF3AgMBAAEwDQYJKoZIhvcNAQELBQADggEBAIs5nI0GNJ8s/6yXNjw+ZPkDxv8s+zEZ3NJSZepdASJy2aIEx/EA/SsDOh2lk3aRjYGJhUMmGRPe/OPqelYq1ed5gnDepjTpkXiQ0vgaeelbDPJZ8y/em7l8JjxQN4t7psSes2j8RZZCIQxmBvxg6vv/Dv6nR1eyVPo6VwW80rN4XRIEn1QbO8loL0wmf06lKRp7l8TJmnZPHfsBvkIcq2AYv/ktztHqp6P6AjEVF5dHnJZ5aotz3xudRA14ufbGTRpuAcTTbbH7ZIi99XuGs83F8oW0McecmSMarTiI9KFWQU7p3Y8uFDvcQgF9xFdqK33wvNsnOoqmM3G+MEFBGks=MIIC2jCCAcKgAwIBAgIQZGfcLJOybI1IfVkwLAsjvzANBgkqhkiG9w0BAQsFADApMScwJQYDVQQDEx5BREZTIFNpZ25pbmcgLSB2YWZzLm51cy5lZHUuc2cwHhcNMjEwNTA0MTUwNTIyWhcNMjQwNTAzMTUwNTIyWjApMScwJQYDVQQDEx5BREZTIFNpZ25pbmcgLSB2YWZzLm51cy5lZHUuc2cwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCQ4NkCXYgBUGWJCsMc9y1/zSijXP8teRE4qBksInkUAmklE6I3kb/39HrO6evOWYXiUBHZS5jCiZlRHeYkp/2dli9N2nn3b6K34fLha6nqYtx9BBWZK5oKu6xQJMIlMdsm1PlMWGc+XvMmZOvPpSzocijC++DfjGAL2V1bLPG2kI6Q3NxR3DiYqTosdvksuFtE/hIYZYhEpZMPu84a3bn0d4ImDDBQV9xq3qqi8FNeuYng/Fz+1rXM7Oh7FXE7zgQXmAPxClsqWAkWpaYvOsAJUfeovwV+YKP9/KaxVNZSXSHCL3eGcdUJb1xGo/u/dI6iLc/RmcHitu5jDMh2iz/PAgMBAAEwDQYJKoZIhvcNAQELBQADggEBADz99ae5b28QT057tjue+hnS7G6/8DNC/5lyXRHoW1NnIzr4kOvJTNlm5fqstTl6CdETTwfjmE25ThH6vRKzMRDEBPAsIDjMMMnGbybJNVrqIvuskwIfs0agO2jXiAPg9LPJjC3bH6KnnDBMnXVNP/aMAT2+KgiJWnGElF/LMYcpn2thPV+tEnVr/2+pYMdTH75LwfqFgSNHT8HUyZ3Cb9W/Z66er3fa2HolHHzkDpoiRMXM34Gsx4ULSRFufVewgi8SRnd1+vDcMav0qGtH1ajsAJ5oqJ+a7Kpf7GDabPSYBbHJsTAKK3P4LNVG9AVskBOKRQl9uBAlIA07MPE/E1U=urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddressurn:oasis:names:tc:SAML:2.0:nameid-format:persistenturn:oasis:names:tc:SAML:2.0:nameid-format:transientNational University of SingaporeNational University of Singaporehttp://www.nus.edu.sg/HiteshRaiCCEMessagingAdmins@nus.edu.sg+65-65167431
\ No newline at end of file diff --git a/backend/auth/sp.xml b/backend/auth/sp.xml new file mode 100644 index 0000000000..8142322f79 --- /dev/null +++ b/backend/auth/sp.xml @@ -0,0 +1,21 @@ + + + + + + + MIICajCCAdOgAwIBAgIBADANBgkqhkiG9w0BAQ0FADBRMQswCQYDVQQGEwJzZzESMBAGA1UECAwJU2luZ2Fwb3JlMRAwDgYDVQQKDAdOVVNNb2RzMRwwGgYDVQQDDBNodHRwczovL251c21vZHMuY29tMCAXDTIxMDIwMTA4MzE0N1oYDzIxMjEwMTA4MDgzMTQ3WjBRMQswCQYDVQQGEwJzZzESMBAGA1UECAwJU2luZ2Fwb3JlMRAwDgYDVQQKDAdOVVNNb2RzMRwwGgYDVQQDDBNodHRwczovL251c21vZHMuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDsUyFzxVrM8jDE8nmb+SEwo64rKvVAxO37W/AXsGIih/2j2ijl+WyGqHN8uDcPZi5hkyFaJ4t2tfdWn1cK1HdUQ1IO2YdKNv3ZvotU1wPoEa3uj6LMb+uOkNIIHM2Lep+E7KCAmZfP3tTAejuD0skHS90DAbV3rl70zkRH7PlbwIDAQABo1AwTjAdBgNVHQ4EFgQUUvQmIWw/43xDFkxbwnQ2D32oFLEwHwYDVR0jBBgwFoAUUvQmIWw/43xDFkxbwnQ2D32oFLEwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQ0FAAOBgQBs+6TosV25k/KIWTPGiNbCBBUTIEiy5SKUPx4e6WsTNSC91dlDlnwiV4Feag4v9RlanOLJI11XFibaw+SPQ1nUvpnfeKf4sU0jIzjoRHzFfd7VpirT5Uy5pmXZ4J01SGGP28PJ/wioxsnIDWe1HVJFbkMzlIBN3Mg/0pwwTJeZ0w== + + + + + + + MIICajCCAdOgAwIBAgIBADANBgkqhkiG9w0BAQ0FADBRMQswCQYDVQQGEwJzZzESMBAGA1UECAwJU2luZ2Fwb3JlMRAwDgYDVQQKDAdOVVNNb2RzMRwwGgYDVQQDDBNodHRwczovL251c21vZHMuY29tMCAXDTIxMDIwMTA4MzE0N1oYDzIxMjEwMTA4MDgzMTQ3WjBRMQswCQYDVQQGEwJzZzESMBAGA1UECAwJU2luZ2Fwb3JlMRAwDgYDVQQKDAdOVVNNb2RzMRwwGgYDVQQDDBNodHRwczovL251c21vZHMuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDsUyFzxVrM8jDE8nmb+SEwo64rKvVAxO37W/AXsGIih/2j2ijl+WyGqHN8uDcPZi5hkyFaJ4t2tfdWn1cK1HdUQ1IO2YdKNv3ZvotU1wPoEa3uj6LMb+uOkNIIHM2Lep+E7KCAmZfP3tTAejuD0skHS90DAbV3rl70zkRH7PlbwIDAQABo1AwTjAdBgNVHQ4EFgQUUvQmIWw/43xDFkxbwnQ2D32oFLEwHwYDVR0jBBgwFoAUUvQmIWw/43xDFkxbwnQ2D32oFLEwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQ0FAAOBgQBs+6TosV25k/KIWTPGiNbCBBUTIEiy5SKUPx4e6WsTNSC91dlDlnwiV4Feag4v9RlanOLJI11XFibaw+SPQ1nUvpnfeKf4sU0jIzjoRHzFfd7VpirT5Uy5pmXZ4J01SGGP28PJ/wioxsnIDWe1HVJFbkMzlIBN3Mg/0pwwTJeZ0w== + + + + urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified + + + diff --git a/backend/crates/nusmods-api/Cargo.toml b/backend/crates/nusmods-api/Cargo.toml index 69fd464dce..deb6e90674 100644 --- a/backend/crates/nusmods-api/Cargo.toml +++ b/backend/crates/nusmods-api/Cargo.toml @@ -13,4 +13,5 @@ clap.workspace = true serde.workspace = true thiserror.workspace = true tokio.workspace = true +tower.workspace = true tracing-subscriber.workspace = true diff --git a/backend/crates/nusmods-api/src/auth.rs b/backend/crates/nusmods-api/src/auth.rs new file mode 100644 index 0000000000..cd07e15b14 --- /dev/null +++ b/backend/crates/nusmods-api/src/auth.rs @@ -0,0 +1,10 @@ +use axum::{routing::get, Router}; + +async fn get_user() -> &'static str { + "User endpoint" +} + +/// Routes for authentication +pub fn auth_routes() -> Router { + Router::new().route("/user", get(get_user)) +} diff --git a/backend/crates/nusmods-api/src/bin/api.rs b/backend/crates/nusmods-api/src/bin/api.rs index 1bf7e12728..6fa97528e1 100644 --- a/backend/crates/nusmods-api/src/bin/api.rs +++ b/backend/crates/nusmods-api/src/bin/api.rs @@ -1,57 +1,25 @@ -use axum::{ - routing::{get, post}, - http::StatusCode, - Json, Router, -}; -use serde::{Deserialize, Serialize}; +use axum::{routing::get, Router}; + +const API_VERSION: &str = "v1"; #[tokio::main] async fn main() { - // initialize tracing tracing_subscriber::fmt::init(); - // build our application with a route + let api_routes = Router::new() + .route("/", get(get_root)) + .nest("/auth", nusmods_api::auth::auth_routes()) + .nest("/reviews", nusmods_api::reviews::reviews_routes()); + let app = Router::new() - // `GET /` goes to `root` - .route("/", get(root)) - // `POST /users` goes to `create_user` - .route("/users", post(create_user)); + .route("/", get(get_root)) + .nest(format!("/{}", API_VERSION).as_str(), api_routes); - // run our app with hyper, listening globally on port 3000 + // Run our app with hyper, listening on port 3000 let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); axum::serve(listener, app).await.unwrap(); } -// basic handler that responds with a static string -async fn root() -> &'static str { - "Hello, World!" -} - -async fn create_user( - // this argument tells axum to parse the request body - // as JSON into a `CreateUser` type - Json(payload): Json, -) -> (StatusCode, Json) { - // insert your application logic here - let user = User { - id: 1337, - username: payload.username, - }; - - // this will be converted into a JSON response - // with a status code of `201 Created` - (StatusCode::CREATED, Json(user)) -} - -// the input to our `create_user` handler -#[derive(Deserialize)] -struct CreateUser { - username: String, +async fn get_root() -> &'static str { + "Welcome to the NUSMods API!" } - -// the output to our `create_user` handler -#[derive(Serialize)] -struct User { - id: u64, - username: String, -} \ No newline at end of file diff --git a/backend/crates/nusmods-api/src/lib.rs b/backend/crates/nusmods-api/src/lib.rs new file mode 100644 index 0000000000..d1fface9e3 --- /dev/null +++ b/backend/crates/nusmods-api/src/lib.rs @@ -0,0 +1,4 @@ +// Alphabetical please + +pub mod auth; +pub mod reviews; diff --git a/backend/crates/nusmods-api/src/reviews.rs b/backend/crates/nusmods-api/src/reviews.rs new file mode 100644 index 0000000000..0c960504a3 --- /dev/null +++ b/backend/crates/nusmods-api/src/reviews.rs @@ -0,0 +1,10 @@ +use axum::{extract::Path, routing::get, Router}; + +async fn get_course_reviews(Path(course_id): Path) -> String { + format!("Course ID: {}", course_id) +} + +/// Routes for reviews +pub fn reviews_routes() -> Router { + Router::new().route("/:course_id", get(get_course_reviews)) +} From fdc546950f2bdaeac5b4afa0bcd42a41132902ee Mon Sep 17 00:00:00 2001 From: Christopher Goh Date: Sun, 17 Dec 2023 19:52:43 +0800 Subject: [PATCH 06/10] Remove unused deps --- backend/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/backend/Cargo.toml b/backend/Cargo.toml index eaa7c1283a..9cb1fd5b6a 100644 --- a/backend/Cargo.toml +++ b/backend/Cargo.toml @@ -17,7 +17,6 @@ ahash = { version = "0.8.6", features = ["serde"] } anyhow = "1.0.75" axum = "0.7.2" clap = { version = "4.4.11", features = ["derive", "env"] } -samael = { version = "0.0.14", features = ["xmlsec"] } serde = { version = "1.0.193", features = ["derive", "rc"] } thiserror = "1.0.51" tower = "0.4.13" From 415f145f67707fa16fb5c2f21eea8a061d366637 Mon Sep 17 00:00:00 2001 From: Christopher Goh Date: Mon, 18 Dec 2023 00:28:29 +0800 Subject: [PATCH 07/10] Add auth endpoints --- backend/Cargo.lock | 574 ++++++++++++++++++++++++- backend/Cargo.toml | 2 + backend/crates/nusmods-api/Cargo.toml | 2 + backend/crates/nusmods-api/src/auth.rs | 112 ++++- 4 files changed, 668 insertions(+), 22 deletions(-) diff --git a/backend/Cargo.lock b/backend/Cargo.lock index b43b88af8e..5ed4112f4a 100644 --- a/backend/Cargo.lock +++ b/backend/Cargo.lock @@ -112,10 +112,10 @@ dependencies = [ "axum-core", "bytes", "futures-util", - "http", - "http-body", + "http 1.0.0", + "http-body 1.0.0", "http-body-util", - "hyper", + "hyper 1.0.1", "hyper-util", "itoa", "matchit", @@ -144,8 +144,8 @@ dependencies = [ "async-trait", "bytes", "futures-util", - "http", - "http-body", + "http 1.0.0", + "http-body 1.0.0", "http-body-util", "mime", "pin-project-lite", @@ -170,12 +170,30 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base64" +version = "0.21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" + [[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + [[package]] name = "bytes" version = "1.5.0" @@ -243,18 +261,74 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "encoding_rs" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +dependencies = [ + "cfg-if", +] + [[package]] name = "equivalent" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + [[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.2.1" @@ -320,6 +394,25 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +[[package]] +name = "h2" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.11", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "h2" version = "0.4.0" @@ -331,7 +424,7 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http", + "http 1.0.0", "indexmap", "slab", "tokio", @@ -357,6 +450,17 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +[[package]] +name = "http" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http" version = "1.0.0" @@ -368,6 +472,17 @@ dependencies = [ "itoa", ] +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http 0.2.11", + "pin-project-lite", +] + [[package]] name = "http-body" version = "1.0.0" @@ -375,7 +490,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" dependencies = [ "bytes", - "http", + "http 1.0.0", ] [[package]] @@ -386,8 +501,8 @@ checksum = "41cb79eb393015dadd30fc252023adb0b2400a0caee0fa2a077e6e21a551e840" dependencies = [ "bytes", "futures-util", - "http", - "http-body", + "http 1.0.0", + "http-body 1.0.0", "pin-project-lite", ] @@ -403,6 +518,30 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "hyper" +version = "0.14.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2 0.3.22", + "http 0.2.11", + "http-body 0.4.6", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.4.10", + "tokio", + "tower-service", + "tracing", + "want", +] + [[package]] name = "hyper" version = "1.0.1" @@ -412,9 +551,9 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "h2", - "http", - "http-body", + "h2 0.4.0", + "http 1.0.0", + "http-body 1.0.0", "httparse", "httpdate", "itoa", @@ -422,6 +561,19 @@ dependencies = [ "tokio", ] +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper 0.14.27", + "native-tls", + "tokio", + "tokio-native-tls", +] + [[package]] name = "hyper-util" version = "0.1.1" @@ -431,17 +583,27 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "http", - "http-body", - "hyper", + "http 1.0.0", + "http-body 1.0.0", + "hyper 1.0.1", "pin-project-lite", - "socket2", + "socket2 0.5.5", "tokio", "tower", "tower-service", "tracing", ] +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "indexmap" version = "2.1.0" @@ -452,12 +614,27 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + [[package]] name = "itoa" version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +[[package]] +name = "js-sys" +version = "0.3.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -470,6 +647,12 @@ version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" +[[package]] +name = "linux-raw-sys" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" + [[package]] name = "lock_api" version = "0.4.11" @@ -524,6 +707,24 @@ dependencies = [ "windows-sys 0.48.0", ] +[[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" @@ -552,11 +753,13 @@ dependencies = [ "anyhow", "axum", "clap", + "reqwest", "serde", "thiserror", "tokio", "tower", "tracing-subscriber", + "url", ] [[package]] @@ -574,6 +777,50 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "openssl" +version = "0.10.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b8419dc8cc6d866deb801274bba2e6f8f6108c1bb7fcc10ee5ab864931dbb45" +dependencies = [ + "bitflags 2.4.1", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3eaad34cdd97d81de97964fc7f29e2d104f483840d906ef56daa1912338460b" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "overload" version = "0.1.1" @@ -641,6 +888,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + [[package]] name = "proc-macro2" version = "1.0.70" @@ -665,7 +918,45 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ - "bitflags", + "bitflags 1.3.2", +] + +[[package]] +name = "reqwest" +version = "0.11.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2 0.3.22", + "http 0.2.11", + "http-body 0.4.6", + "hyper 0.14.27", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "system-configuration", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", ] [[package]] @@ -674,6 +965,19 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +[[package]] +name = "rustix" +version = "0.38.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" +dependencies = [ + "bitflags 2.4.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + [[package]] name = "rustversion" version = "1.0.14" @@ -686,12 +990,44 @@ version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +[[package]] +name = "schannel" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +dependencies = [ + "windows-sys 0.48.0", +] + [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "serde" version = "1.0.193" @@ -778,6 +1114,16 @@ version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "socket2" version = "0.5.5" @@ -811,6 +1157,40 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tempfile" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall", + "rustix", + "windows-sys 0.48.0", +] + [[package]] name = "thiserror" version = "1.0.51" @@ -841,6 +1221,21 @@ dependencies = [ "once_cell", ] +[[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tokio" version = "1.35.0" @@ -855,7 +1250,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2", + "socket2 0.5.5", "tokio-macros", "windows-sys 0.48.0", ] @@ -871,6 +1266,16 @@ dependencies = [ "syn", ] +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + [[package]] name = "tokio-util" version = "0.7.10" @@ -959,12 +1364,44 @@ dependencies = [ "tracing-log", ] +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "unicode-bidi" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" + [[package]] name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "url" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + [[package]] name = "utf8parse" version = "0.2.1" @@ -977,18 +1414,109 @@ 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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + [[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.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" + +[[package]] +name = "web-sys" +version = "0.3.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "winapi" version = "0.3.9" @@ -1143,6 +1671,16 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "zerocopy" version = "0.7.31" diff --git a/backend/Cargo.toml b/backend/Cargo.toml index 9cb1fd5b6a..7ca53e4924 100644 --- a/backend/Cargo.toml +++ b/backend/Cargo.toml @@ -17,8 +17,10 @@ ahash = { version = "0.8.6", features = ["serde"] } anyhow = "1.0.75" axum = "0.7.2" clap = { version = "4.4.11", features = ["derive", "env"] } +reqwest = { version = "0.11.22", features = ["json"] } serde = { version = "1.0.193", features = ["derive", "rc"] } thiserror = "1.0.51" tower = "0.4.13" tokio = { version = "1.35.0", features = ["full"] } tracing-subscriber = "0.3.18" +url = "2.5.0" diff --git a/backend/crates/nusmods-api/Cargo.toml b/backend/crates/nusmods-api/Cargo.toml index deb6e90674..39256c840b 100644 --- a/backend/crates/nusmods-api/Cargo.toml +++ b/backend/crates/nusmods-api/Cargo.toml @@ -10,8 +10,10 @@ ahash.workspace = true anyhow.workspace = true axum.workspace = true clap.workspace = true +reqwest.workspace = true serde.workspace = true thiserror.workspace = true tokio.workspace = true tower.workspace = true tracing-subscriber.workspace = true +url.workspace = true diff --git a/backend/crates/nusmods-api/src/auth.rs b/backend/crates/nusmods-api/src/auth.rs index cd07e15b14..9b4104f4ee 100644 --- a/backend/crates/nusmods-api/src/auth.rs +++ b/backend/crates/nusmods-api/src/auth.rs @@ -1,10 +1,114 @@ -use axum::{routing::get, Router}; +use axum::{ + extract::Query, + http::{HeaderMap, StatusCode}, + response::{IntoResponse, Redirect}, + routing::get, + Json, Router, +}; +use serde::{Deserialize, Serialize}; +use url::Url; -async fn get_user() -> &'static str { - "User endpoint" +const ALLOWED_CALLBACK_DOMAINS: [&str; 4] = + ["nusmods.com", "nuscourses.com", "modsn.us", "localhost"]; + +const USER_DETAILS_ENDPOINT: &str = + "https://nusmods-website-git-chris-add-user-endpoint-mods-bot.vercel.app/api/nus/auth/user"; +const SSO_LINK_ENDPOINT: &str = + "https://nusmods-website-git-chris-add-user-endpoint-mods-bot.vercel.app/api/nus/auth/sso"; + +fn is_valid_callback_url(callback_url: &str) -> bool { + let url = match Url::parse(callback_url) { + Ok(url) => url, + Err(_) => return false, // Invalid URL + }; + + let host = url.host_str().map(|h| h.to_lowercase()); + + host.map(|host| { + ALLOWED_CALLBACK_DOMAINS.iter().any(|allowed_domain| { + host.ends_with(&format!(".{}", allowed_domain)) || &host == allowed_domain + }) + }) + .unwrap_or(false) +} + +async fn query_user_saml_details(token: &str) -> anyhow::Result { + let client = reqwest::Client::new(); + let saml_user = client + .get(USER_DETAILS_ENDPOINT) + .header("Authorization", token) + .send() + .await? + .json::() + .await?; + Ok(saml_user) +} + +async fn query_login_url(callback: &str) -> anyhow::Result { + let client = reqwest::Client::new(); + let login_url = client + .get(SSO_LINK_ENDPOINT) + .query(&[("callback", callback)]) + .send() + .await? + .text() + .await?; + Ok(login_url) +} + +async fn get_user( + headers: HeaderMap, + Query(query): Query, +) -> Result { + let token = match query.token { + Some(token) => token, + None => headers + .get("Authorization") + .and_then(|header| header.to_str().ok()) + .ok_or(StatusCode::BAD_REQUEST)? + .to_owned(), + }; + + let result = query_user_saml_details(&token).await; + match result { + Ok(user) => Ok(Json(user)), + Err(_) => Err(StatusCode::UNAUTHORIZED), + } +} + +async fn get_login_url(Query(query): Query) -> Result { + let callback = query.callback; + if !is_valid_callback_url(&callback) { + return Err(StatusCode::BAD_REQUEST); + } + let login_url = query_login_url(&callback).await; + match login_url { + Ok(login_url) => Ok(Redirect::to(&login_url)), + Err(_) => Err(StatusCode::INTERNAL_SERVER_ERROR), + } } /// Routes for authentication pub fn auth_routes() -> Router { - Router::new().route("/user", get(get_user)) + Router::new() + .route("/user", get(get_user)) + .route("/login", get(get_login_url)) +} + +#[derive(Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +struct SamlUser { + account_name: String, + upn: String, + email: String, +} + +#[derive(Deserialize)] +struct GetLogin { + callback: String, +} + +#[derive(Deserialize)] +struct GetUser { + token: Option, } From 51cd05c23d8375ac6bb58b19d23a1b9d98fc0627 Mon Sep 17 00:00:00 2001 From: Christopher Goh Date: Mon, 18 Dec 2023 00:44:02 +0800 Subject: [PATCH 08/10] Add auth endpoints --- backend/crates/nusmods-api/src/auth.rs | 51 ++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/backend/crates/nusmods-api/src/auth.rs b/backend/crates/nusmods-api/src/auth.rs index 9b4104f4ee..c967b5495d 100644 --- a/backend/crates/nusmods-api/src/auth.rs +++ b/backend/crates/nusmods-api/src/auth.rs @@ -11,10 +11,8 @@ use url::Url; const ALLOWED_CALLBACK_DOMAINS: [&str; 4] = ["nusmods.com", "nuscourses.com", "modsn.us", "localhost"]; -const USER_DETAILS_ENDPOINT: &str = - "https://nusmods-website-git-chris-add-user-endpoint-mods-bot.vercel.app/api/nus/auth/user"; -const SSO_LINK_ENDPOINT: &str = - "https://nusmods-website-git-chris-add-user-endpoint-mods-bot.vercel.app/api/nus/auth/sso"; +const USER_DETAILS_ENDPOINT: &str = "https://nusmods.com/api/nus/auth/user"; +const SSO_LINK_ENDPOINT: &str = "https://nusmods.com/api/nus/auth/sso"; fn is_valid_callback_url(callback_url: &str) -> bool { let url = match Url::parse(callback_url) { @@ -112,3 +110,48 @@ struct GetLogin { struct GetUser { token: Option, } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_is_valid_callback_url_canonical() { + assert!(is_valid_callback_url("http://nusmods.com")); + assert!(is_valid_callback_url("http://nusmods.com/some/path")); + assert!(is_valid_callback_url("http://nuscourses.com")); + assert!(is_valid_callback_url("http://nuscourses.com/some/path")); + assert!(is_valid_callback_url("http://modsn.us")); + assert!(is_valid_callback_url("http://modsn.us/some/path")); + assert!(is_valid_callback_url("http://localhost:3000")); + assert!(is_valid_callback_url("http://localhost:3000/some/path")); + } + + #[test] + fn test_is_valid_callback_url_subdomain() { + assert!(is_valid_callback_url("http://api.nusmods.com")); + assert!(is_valid_callback_url("http://api.nusmods.com/some/path")); + assert!(is_valid_callback_url("http://api.nuscourses.com")); + assert!(is_valid_callback_url("http://api.nuscourses.com/some/path")); + assert!(is_valid_callback_url("http://api.modsn.us")); + assert!(is_valid_callback_url("http://api.modsn.us/some/path")); + assert!(is_valid_callback_url("http://api.localhost:3000")); + assert!(is_valid_callback_url("http://api.localhost:3000/some/path")); + } + + #[test] + fn test_is_valid_callback_url_malicious_domain() { + assert!(!is_valid_callback_url("http://maliciousnusmods.com")); + assert!(!is_valid_callback_url( + "http://maliciousnusmods.com/some/path" + )); + assert!(!is_valid_callback_url("http://api.maliciousnusmods.com")); + assert!(!is_valid_callback_url( + "http://api.maliciousnusmods.com/some/path" + )); + assert!(!is_valid_callback_url("http://nusmods.com.malicious.com")); + assert!(!is_valid_callback_url( + "http://nusmods.com.malicious.com/some/path" + )); + } +} From 053391c3264f556abe79ef3c3240f525c272de58 Mon Sep 17 00:00:00 2001 From: Christopher Goh Date: Mon, 18 Dec 2023 01:08:09 +0800 Subject: [PATCH 09/10] Add CI script --- backend/ci.sh | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100755 backend/ci.sh diff --git a/backend/ci.sh b/backend/ci.sh new file mode 100755 index 0000000000..c0fcfdf3ba --- /dev/null +++ b/backend/ci.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +set -e + +cargo_dir=$(dirname $(which cargo)) + +if [ ! -x "$cargo_dir/cargo-audit" ]; then + echo "cargo-audit is not found in the same directory as cargo. Installing..." + cargo install cargo-audit +fi + +cargo fmt --check --all && +cargo clippy --all-targets --all-features -- -D warnings && +cargo check --all-targets --all-features && +cargo test --all-targets --all-features && +cargo build --profile=aggressive --all-targets --all-features && +cargo audit && +echo CI OK From ee789f63dce2f6e3501652747c8373706b048a2b Mon Sep 17 00:00:00 2001 From: Christopher Goh Date: Mon, 18 Dec 2023 01:14:00 +0800 Subject: [PATCH 10/10] Add comments --- backend/auth/FederationMetadata.xml | 1 - backend/auth/sp.xml | 21 --------------------- backend/crates/nusmods-api/src/auth.rs | 9 ++++++++- 3 files changed, 8 insertions(+), 23 deletions(-) delete mode 100644 backend/auth/FederationMetadata.xml delete mode 100644 backend/auth/sp.xml diff --git a/backend/auth/FederationMetadata.xml b/backend/auth/FederationMetadata.xml deleted file mode 100644 index 7a27f5de7d..0000000000 --- a/backend/auth/FederationMetadata.xml +++ /dev/null @@ -1 +0,0 @@ -EMBTkCa4qOswlQ4vwNt+G5Em8Eww/HV8mpbPyGWjt6I=HdmYWtNTCOacUxZonZbbeyG61EFMGYXLw/IldX7F7lwpQQRxqlcTIHayyU2ZJBnmqoKxKElzXIDjkbzBvPi66FXW7rI2oqM4n9Nz7DmQrdvmSKW0haf4vwavBmEO4qktCfwpgwb4vIWfmJOeHnNMHQHV2QkgYrTw1wES6YUY6ChWWhG1vEhPyQJ8VlUvs3WAuHExfl0Nbn5h+z9iSGxzcLSr/wZT6dJaoGcU5CX//UAB3ozMfOvNSLvp44QraG+keTVBKsiuNHFy7CkSLwrLE+lcWTSyc6EcXVRvq8iNYfBA8NGM/6EQMQszRpXzmEMZsWfydRm/L68fvAhKlr5tFA==MIIC2jCCAcKgAwIBAgIQZGfcLJOybI1IfVkwLAsjvzANBgkqhkiG9w0BAQsFADApMScwJQYDVQQDEx5BREZTIFNpZ25pbmcgLSB2YWZzLm51cy5lZHUuc2cwHhcNMjEwNTA0MTUwNTIyWhcNMjQwNTAzMTUwNTIyWjApMScwJQYDVQQDEx5BREZTIFNpZ25pbmcgLSB2YWZzLm51cy5lZHUuc2cwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCQ4NkCXYgBUGWJCsMc9y1/zSijXP8teRE4qBksInkUAmklE6I3kb/39HrO6evOWYXiUBHZS5jCiZlRHeYkp/2dli9N2nn3b6K34fLha6nqYtx9BBWZK5oKu6xQJMIlMdsm1PlMWGc+XvMmZOvPpSzocijC++DfjGAL2V1bLPG2kI6Q3NxR3DiYqTosdvksuFtE/hIYZYhEpZMPu84a3bn0d4ImDDBQV9xq3qqi8FNeuYng/Fz+1rXM7Oh7FXE7zgQXmAPxClsqWAkWpaYvOsAJUfeovwV+YKP9/KaxVNZSXSHCL3eGcdUJb1xGo/u/dI6iLc/RmcHitu5jDMh2iz/PAgMBAAEwDQYJKoZIhvcNAQELBQADggEBADz99ae5b28QT057tjue+hnS7G6/8DNC/5lyXRHoW1NnIzr4kOvJTNlm5fqstTl6CdETTwfjmE25ThH6vRKzMRDEBPAsIDjMMMnGbybJNVrqIvuskwIfs0agO2jXiAPg9LPJjC3bH6KnnDBMnXVNP/aMAT2+KgiJWnGElF/LMYcpn2thPV+tEnVr/2+pYMdTH75LwfqFgSNHT8HUyZ3Cb9W/Z66er3fa2HolHHzkDpoiRMXM34Gsx4ULSRFufVewgi8SRnd1+vDcMav0qGtH1ajsAJ5oqJ+a7Kpf7GDabPSYBbHJsTAKK3P4LNVG9AVskBOKRQl9uBAlIA07MPE/E1U=MIIC4DCCAcigAwIBAgIQXm7+axsX6IRO+Aj+zpzU3DANBgkqhkiG9w0BAQsFADAsMSowKAYDVQQDEyFBREZTIEVuY3J5cHRpb24gLSB2YWZzLm51cy5lZHUuc2cwHhcNMjEwNTA0MTUwNTI3WhcNMjQwNTAzMTUwNTI3WjAsMSowKAYDVQQDEyFBREZTIEVuY3J5cHRpb24gLSB2YWZzLm51cy5lZHUuc2cwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCcqQ7nnhRAJpolHmE5ZvhtnlsNNcBrFVqxwX3ESJdHfy2gV0t5UEWyMyVHaHSc1TPitTfu1iuHFZcfqz+IQnbc/PsLf/KTJsqDmyCk/JmftacIj5BLdIp4ptI2gJXPiiPcIdCVf9vd4RDaa8huLlcSSGY4itRjdPvk/lOiI/J7jeUEnHSiPveMwxJD+EHFqzImbj6acARO7t8QWxPcp1glPxY10PO94tXHHy2CuWeA3CKj7tg2J+NTb2RFWnkOnsUp1UtUJw7E60jmLoXo+bVCjes95KNPXdkVxdtRmkHbSdo2vKl1DdiMM6jt5lvapox8XRzWsX4/YaQZtgZa9FF3AgMBAAEwDQYJKoZIhvcNAQELBQADggEBAIs5nI0GNJ8s/6yXNjw+ZPkDxv8s+zEZ3NJSZepdASJy2aIEx/EA/SsDOh2lk3aRjYGJhUMmGRPe/OPqelYq1ed5gnDepjTpkXiQ0vgaeelbDPJZ8y/em7l8JjxQN4t7psSes2j8RZZCIQxmBvxg6vv/Dv6nR1eyVPo6VwW80rN4XRIEn1QbO8loL0wmf06lKRp7l8TJmnZPHfsBvkIcq2AYv/ktztHqp6P6AjEVF5dHnJZ5aotz3xudRA14ufbGTRpuAcTTbbH7ZIi99XuGs83F8oW0McecmSMarTiI9KFWQU7p3Y8uFDvcQgF9xFdqK33wvNsnOoqmM3G+MEFBGks=E-Mail AddressThe e-mail address of the userGiven NameThe given name of the userNameThe unique name of the userUPNThe user principal name (UPN) of the userCommon NameThe common name of the userAD FS 1.x E-Mail AddressThe e-mail address of the user when interoperating with AD FS 1.1 or AD FS 1.0GroupA group that the user is a member ofAD FS 1.x UPNThe UPN of the user when interoperating with AD FS 1.1 or AD FS 1.0RoleA role that the user hasSurnameThe surname of the userPPIDThe private identifier of the userName IDThe SAML name identifier of the userAuthentication time stampUsed to display the time and date that the user was authenticatedAuthentication methodThe method used to authenticate the userDeny only group SIDThe deny-only group SID of the userDeny only primary SIDThe deny-only primary SID of the userDeny only primary group SIDThe deny-only primary group SID of the userGroup SIDThe group SID of the userPrimary group SIDThe primary group SID of the userPrimary SIDThe primary SID of the userWindows account nameThe domain account name of the user in the form of domain\userIs Registered UserUser is registered to use this deviceDevice IdentifierIdentifier of the deviceDevice Registration IdentifierIdentifier for Device RegistrationDevice Registration DisplayNameDisplay name of Device RegistrationDevice OS typeOS type of the deviceDevice OS VersionOS version of the deviceIs Managed DeviceDevice is managed by a management serviceForwarded Client IPIP address of the userClient ApplicationType of the Client ApplicationClient User AgentDevice type the client is using to access the applicationClient IPIP address of the clientEndpoint PathAbsolute Endpoint path which can be used to determine active versus passive clientsProxyDNS name of the federation server proxy that passed the requestApplication IdentifierIdentifier for the Relying PartyApplication policiesApplication policies of the certificateAuthority Key IdentifierThe Authority Key Identifier extension of the certificate that signed an issued certificateBasic ConstraintOne of the basic constraints of the certificateEnhanced Key UsageDescribes one of the enhanced key usages of the certificateIssuerThe name of the certificate authority that issued the X.509 certificateIssuer NameThe distinguished name of the certificate issuerKey UsageOne of the key usages of the certificateNot AfterDate in local time after which a certificate is no longer validNot BeforeThe date in local time on which a certificate becomes validCertificate PoliciesThe policies under which the certificate has been issuedPublic KeyPublic Key of the certificateCertificate Raw DataThe raw data of the certificateSubject Alternative NameOne of the alternative names of the certificateSerial NumberThe serial number of a certificateSignature AlgorithmThe algorithm used to create the signature of a certificateSubjectThe subject from the certificateSubject Key IdentifierDescribes the subject key identifier of the certificateSubject NameThe subject distinguished name from a certificateV2 Template NameThe name of the version 2 certificate template used when issuing or renewing a certificate. The extension is Microsoft specific.V1 Template NameThe name of the version 1 certificate template used when issuing or renewing a certificate. The extension is Microsoft specific.ThumbprintThumbprint of the certificateX.509 VersionThe X.509 format version of a certificateInside Corporate NetworkUsed to indicate if a request originated inside corporate networkPassword Expiration TimeUsed to display the time when the password expiresPassword Expiration DaysUsed to display the number of days to password expiryUpdate Password URLUsed to display the web address of update password serviceAuthentication Methods ReferencesUsed to indicate all authentication methods used to authenticate the userClient Request IDIdentifier for a user sessionAlternate Login IDAlternate login ID of the userdisplayNamemailmail (inetOrgPerson)SamAccountNameAD SamAccountName (userid)
https://vafs.nus.edu.sg/adfs/services/trust/2005/issuedtokenmixedasymmetricbasic256
https://vafs.nus.edu.sg/adfs/services/trust/2005/issuedtokenmixedsymmetricbasic256
https://vafs.nus.edu.sg/adfs/services/trust/13/issuedtokenmixedasymmetricbasic256
https://vafs.nus.edu.sg/adfs/services/trust/13/issuedtokenmixedsymmetricbasic256
https://vafs.nus.edu.sg/adfs/ls/
https://vafs.nus.edu.sg/adfs/services/trust
https://vafs.nus.edu.sg/adfs/services/trust/2005/issuedtokenmixedasymmetricbasic256
https://vafs.nus.edu.sg/adfs/ls/
MIIC2jCCAcKgAwIBAgIQZGfcLJOybI1IfVkwLAsjvzANBgkqhkiG9w0BAQsFADApMScwJQYDVQQDEx5BREZTIFNpZ25pbmcgLSB2YWZzLm51cy5lZHUuc2cwHhcNMjEwNTA0MTUwNTIyWhcNMjQwNTAzMTUwNTIyWjApMScwJQYDVQQDEx5BREZTIFNpZ25pbmcgLSB2YWZzLm51cy5lZHUuc2cwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCQ4NkCXYgBUGWJCsMc9y1/zSijXP8teRE4qBksInkUAmklE6I3kb/39HrO6evOWYXiUBHZS5jCiZlRHeYkp/2dli9N2nn3b6K34fLha6nqYtx9BBWZK5oKu6xQJMIlMdsm1PlMWGc+XvMmZOvPpSzocijC++DfjGAL2V1bLPG2kI6Q3NxR3DiYqTosdvksuFtE/hIYZYhEpZMPu84a3bn0d4ImDDBQV9xq3qqi8FNeuYng/Fz+1rXM7Oh7FXE7zgQXmAPxClsqWAkWpaYvOsAJUfeovwV+YKP9/KaxVNZSXSHCL3eGcdUJb1xGo/u/dI6iLc/RmcHitu5jDMh2iz/PAgMBAAEwDQYJKoZIhvcNAQELBQADggEBADz99ae5b28QT057tjue+hnS7G6/8DNC/5lyXRHoW1NnIzr4kOvJTNlm5fqstTl6CdETTwfjmE25ThH6vRKzMRDEBPAsIDjMMMnGbybJNVrqIvuskwIfs0agO2jXiAPg9LPJjC3bH6KnnDBMnXVNP/aMAT2+KgiJWnGElF/LMYcpn2thPV+tEnVr/2+pYMdTH75LwfqFgSNHT8HUyZ3Cb9W/Z66er3fa2HolHHzkDpoiRMXM34Gsx4ULSRFufVewgi8SRnd1+vDcMav0qGtH1ajsAJ5oqJ+a7Kpf7GDabPSYBbHJsTAKK3P4LNVG9AVskBOKRQl9uBAlIA07MPE/E1U=E-Mail AddressThe e-mail address of the userGiven NameThe given name of the userNameThe unique name of the userUPNThe user principal name (UPN) of the userCommon NameThe common name of the userAD FS 1.x E-Mail AddressThe e-mail address of the user when interoperating with AD FS 1.1 or AD FS 1.0GroupA group that the user is a member ofAD FS 1.x UPNThe UPN of the user when interoperating with AD FS 1.1 or AD FS 1.0RoleA role that the user hasSurnameThe surname of the userPPIDThe private identifier of the userName IDThe SAML name identifier of the userAuthentication time stampUsed to display the time and date that the user was authenticatedAuthentication methodThe method used to authenticate the userDeny only group SIDThe deny-only group SID of the userDeny only primary SIDThe deny-only primary SID of the userDeny only primary group SIDThe deny-only primary group SID of the userGroup SIDThe group SID of the userPrimary group SIDThe primary group SID of the userPrimary SIDThe primary SID of the userWindows account nameThe domain account name of the user in the form of domain\userIs Registered UserUser is registered to use this deviceDevice IdentifierIdentifier of the deviceDevice Registration IdentifierIdentifier for Device RegistrationDevice Registration DisplayNameDisplay name of Device RegistrationDevice OS typeOS type of the deviceDevice OS VersionOS version of the deviceIs Managed DeviceDevice is managed by a management serviceForwarded Client IPIP address of the userClient ApplicationType of the Client ApplicationClient User AgentDevice type the client is using to access the applicationClient IPIP address of the clientEndpoint PathAbsolute Endpoint path which can be used to determine active versus passive clientsProxyDNS name of the federation server proxy that passed the requestApplication IdentifierIdentifier for the Relying PartyApplication policiesApplication policies of the certificateAuthority Key IdentifierThe Authority Key Identifier extension of the certificate that signed an issued certificateBasic ConstraintOne of the basic constraints of the certificateEnhanced Key UsageDescribes one of the enhanced key usages of the certificateIssuerThe name of the certificate authority that issued the X.509 certificateIssuer NameThe distinguished name of the certificate issuerKey UsageOne of the key usages of the certificateNot AfterDate in local time after which a certificate is no longer validNot BeforeThe date in local time on which a certificate becomes validCertificate PoliciesThe policies under which the certificate has been issuedPublic KeyPublic Key of the certificateCertificate Raw DataThe raw data of the certificateSubject Alternative NameOne of the alternative names of the certificateSerial NumberThe serial number of a certificateSignature AlgorithmThe algorithm used to create the signature of a certificateSubjectThe subject from the certificateSubject Key IdentifierDescribes the subject key identifier of the certificateSubject NameThe subject distinguished name from a certificateV2 Template NameThe name of the version 2 certificate template used when issuing or renewing a certificate. The extension is Microsoft specific.V1 Template NameThe name of the version 1 certificate template used when issuing or renewing a certificate. The extension is Microsoft specific.ThumbprintThumbprint of the certificateX.509 VersionThe X.509 format version of a certificateInside Corporate NetworkUsed to indicate if a request originated inside corporate networkPassword Expiration TimeUsed to display the time when the password expiresPassword Expiration DaysUsed to display the number of days to password expiryUpdate Password URLUsed to display the web address of update password serviceAuthentication Methods ReferencesUsed to indicate all authentication methods used to authenticate the userClient Request IDIdentifier for a user sessionAlternate Login IDAlternate login ID of the userdisplayNamemailmail (inetOrgPerson)SamAccountNameAD SamAccountName (userid)eduPersonTargetedIDeduPersonTargetedIDuidAD UID attributeeduPersonPrincipalNameeduPersonAffiliationProxy AddressesmemberOfcountry
https://vafs.nus.edu.sg/adfs/services/trust/2005/certificatemixed
https://vafs.nus.edu.sg/adfs/services/trust/mex
https://vafs.nus.edu.sg/adfs/ls/
MIIC4DCCAcigAwIBAgIQXm7+axsX6IRO+Aj+zpzU3DANBgkqhkiG9w0BAQsFADAsMSowKAYDVQQDEyFBREZTIEVuY3J5cHRpb24gLSB2YWZzLm51cy5lZHUuc2cwHhcNMjEwNTA0MTUwNTI3WhcNMjQwNTAzMTUwNTI3WjAsMSowKAYDVQQDEyFBREZTIEVuY3J5cHRpb24gLSB2YWZzLm51cy5lZHUuc2cwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCcqQ7nnhRAJpolHmE5ZvhtnlsNNcBrFVqxwX3ESJdHfy2gV0t5UEWyMyVHaHSc1TPitTfu1iuHFZcfqz+IQnbc/PsLf/KTJsqDmyCk/JmftacIj5BLdIp4ptI2gJXPiiPcIdCVf9vd4RDaa8huLlcSSGY4itRjdPvk/lOiI/J7jeUEnHSiPveMwxJD+EHFqzImbj6acARO7t8QWxPcp1glPxY10PO94tXHHy2CuWeA3CKj7tg2J+NTb2RFWnkOnsUp1UtUJw7E60jmLoXo+bVCjes95KNPXdkVxdtRmkHbSdo2vKl1DdiMM6jt5lvapox8XRzWsX4/YaQZtgZa9FF3AgMBAAEwDQYJKoZIhvcNAQELBQADggEBAIs5nI0GNJ8s/6yXNjw+ZPkDxv8s+zEZ3NJSZepdASJy2aIEx/EA/SsDOh2lk3aRjYGJhUMmGRPe/OPqelYq1ed5gnDepjTpkXiQ0vgaeelbDPJZ8y/em7l8JjxQN4t7psSes2j8RZZCIQxmBvxg6vv/Dv6nR1eyVPo6VwW80rN4XRIEn1QbO8loL0wmf06lKRp7l8TJmnZPHfsBvkIcq2AYv/ktztHqp6P6AjEVF5dHnJZ5aotz3xudRA14ufbGTRpuAcTTbbH7ZIi99XuGs83F8oW0McecmSMarTiI9KFWQU7p3Y8uFDvcQgF9xFdqK33wvNsnOoqmM3G+MEFBGks=MIIC2jCCAcKgAwIBAgIQZGfcLJOybI1IfVkwLAsjvzANBgkqhkiG9w0BAQsFADApMScwJQYDVQQDEx5BREZTIFNpZ25pbmcgLSB2YWZzLm51cy5lZHUuc2cwHhcNMjEwNTA0MTUwNTIyWhcNMjQwNTAzMTUwNTIyWjApMScwJQYDVQQDEx5BREZTIFNpZ25pbmcgLSB2YWZzLm51cy5lZHUuc2cwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCQ4NkCXYgBUGWJCsMc9y1/zSijXP8teRE4qBksInkUAmklE6I3kb/39HrO6evOWYXiUBHZS5jCiZlRHeYkp/2dli9N2nn3b6K34fLha6nqYtx9BBWZK5oKu6xQJMIlMdsm1PlMWGc+XvMmZOvPpSzocijC++DfjGAL2V1bLPG2kI6Q3NxR3DiYqTosdvksuFtE/hIYZYhEpZMPu84a3bn0d4ImDDBQV9xq3qqi8FNeuYng/Fz+1rXM7Oh7FXE7zgQXmAPxClsqWAkWpaYvOsAJUfeovwV+YKP9/KaxVNZSXSHCL3eGcdUJb1xGo/u/dI6iLc/RmcHitu5jDMh2iz/PAgMBAAEwDQYJKoZIhvcNAQELBQADggEBADz99ae5b28QT057tjue+hnS7G6/8DNC/5lyXRHoW1NnIzr4kOvJTNlm5fqstTl6CdETTwfjmE25ThH6vRKzMRDEBPAsIDjMMMnGbybJNVrqIvuskwIfs0agO2jXiAPg9LPJjC3bH6KnnDBMnXVNP/aMAT2+KgiJWnGElF/LMYcpn2thPV+tEnVr/2+pYMdTH75LwfqFgSNHT8HUyZ3Cb9W/Z66er3fa2HolHHzkDpoiRMXM34Gsx4ULSRFufVewgi8SRnd1+vDcMav0qGtH1ajsAJ5oqJ+a7Kpf7GDabPSYBbHJsTAKK3P4LNVG9AVskBOKRQl9uBAlIA07MPE/E1U=urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddressurn:oasis:names:tc:SAML:2.0:nameid-format:persistenturn:oasis:names:tc:SAML:2.0:nameid-format:transientMIIC4DCCAcigAwIBAgIQXm7+axsX6IRO+Aj+zpzU3DANBgkqhkiG9w0BAQsFADAsMSowKAYDVQQDEyFBREZTIEVuY3J5cHRpb24gLSB2YWZzLm51cy5lZHUuc2cwHhcNMjEwNTA0MTUwNTI3WhcNMjQwNTAzMTUwNTI3WjAsMSowKAYDVQQDEyFBREZTIEVuY3J5cHRpb24gLSB2YWZzLm51cy5lZHUuc2cwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCcqQ7nnhRAJpolHmE5ZvhtnlsNNcBrFVqxwX3ESJdHfy2gV0t5UEWyMyVHaHSc1TPitTfu1iuHFZcfqz+IQnbc/PsLf/KTJsqDmyCk/JmftacIj5BLdIp4ptI2gJXPiiPcIdCVf9vd4RDaa8huLlcSSGY4itRjdPvk/lOiI/J7jeUEnHSiPveMwxJD+EHFqzImbj6acARO7t8QWxPcp1glPxY10PO94tXHHy2CuWeA3CKj7tg2J+NTb2RFWnkOnsUp1UtUJw7E60jmLoXo+bVCjes95KNPXdkVxdtRmkHbSdo2vKl1DdiMM6jt5lvapox8XRzWsX4/YaQZtgZa9FF3AgMBAAEwDQYJKoZIhvcNAQELBQADggEBAIs5nI0GNJ8s/6yXNjw+ZPkDxv8s+zEZ3NJSZepdASJy2aIEx/EA/SsDOh2lk3aRjYGJhUMmGRPe/OPqelYq1ed5gnDepjTpkXiQ0vgaeelbDPJZ8y/em7l8JjxQN4t7psSes2j8RZZCIQxmBvxg6vv/Dv6nR1eyVPo6VwW80rN4XRIEn1QbO8loL0wmf06lKRp7l8TJmnZPHfsBvkIcq2AYv/ktztHqp6P6AjEVF5dHnJZ5aotz3xudRA14ufbGTRpuAcTTbbH7ZIi99XuGs83F8oW0McecmSMarTiI9KFWQU7p3Y8uFDvcQgF9xFdqK33wvNsnOoqmM3G+MEFBGks=MIIC2jCCAcKgAwIBAgIQZGfcLJOybI1IfVkwLAsjvzANBgkqhkiG9w0BAQsFADApMScwJQYDVQQDEx5BREZTIFNpZ25pbmcgLSB2YWZzLm51cy5lZHUuc2cwHhcNMjEwNTA0MTUwNTIyWhcNMjQwNTAzMTUwNTIyWjApMScwJQYDVQQDEx5BREZTIFNpZ25pbmcgLSB2YWZzLm51cy5lZHUuc2cwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCQ4NkCXYgBUGWJCsMc9y1/zSijXP8teRE4qBksInkUAmklE6I3kb/39HrO6evOWYXiUBHZS5jCiZlRHeYkp/2dli9N2nn3b6K34fLha6nqYtx9BBWZK5oKu6xQJMIlMdsm1PlMWGc+XvMmZOvPpSzocijC++DfjGAL2V1bLPG2kI6Q3NxR3DiYqTosdvksuFtE/hIYZYhEpZMPu84a3bn0d4ImDDBQV9xq3qqi8FNeuYng/Fz+1rXM7Oh7FXE7zgQXmAPxClsqWAkWpaYvOsAJUfeovwV+YKP9/KaxVNZSXSHCL3eGcdUJb1xGo/u/dI6iLc/RmcHitu5jDMh2iz/PAgMBAAEwDQYJKoZIhvcNAQELBQADggEBADz99ae5b28QT057tjue+hnS7G6/8DNC/5lyXRHoW1NnIzr4kOvJTNlm5fqstTl6CdETTwfjmE25ThH6vRKzMRDEBPAsIDjMMMnGbybJNVrqIvuskwIfs0agO2jXiAPg9LPJjC3bH6KnnDBMnXVNP/aMAT2+KgiJWnGElF/LMYcpn2thPV+tEnVr/2+pYMdTH75LwfqFgSNHT8HUyZ3Cb9W/Z66er3fa2HolHHzkDpoiRMXM34Gsx4ULSRFufVewgi8SRnd1+vDcMav0qGtH1ajsAJ5oqJ+a7Kpf7GDabPSYBbHJsTAKK3P4LNVG9AVskBOKRQl9uBAlIA07MPE/E1U=urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddressurn:oasis:names:tc:SAML:2.0:nameid-format:persistenturn:oasis:names:tc:SAML:2.0:nameid-format:transientNational University of SingaporeNational University of Singaporehttp://www.nus.edu.sg/HiteshRaiCCEMessagingAdmins@nus.edu.sg+65-65167431
\ No newline at end of file diff --git a/backend/auth/sp.xml b/backend/auth/sp.xml deleted file mode 100644 index 8142322f79..0000000000 --- a/backend/auth/sp.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - MIICajCCAdOgAwIBAgIBADANBgkqhkiG9w0BAQ0FADBRMQswCQYDVQQGEwJzZzESMBAGA1UECAwJU2luZ2Fwb3JlMRAwDgYDVQQKDAdOVVNNb2RzMRwwGgYDVQQDDBNodHRwczovL251c21vZHMuY29tMCAXDTIxMDIwMTA4MzE0N1oYDzIxMjEwMTA4MDgzMTQ3WjBRMQswCQYDVQQGEwJzZzESMBAGA1UECAwJU2luZ2Fwb3JlMRAwDgYDVQQKDAdOVVNNb2RzMRwwGgYDVQQDDBNodHRwczovL251c21vZHMuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDsUyFzxVrM8jDE8nmb+SEwo64rKvVAxO37W/AXsGIih/2j2ijl+WyGqHN8uDcPZi5hkyFaJ4t2tfdWn1cK1HdUQ1IO2YdKNv3ZvotU1wPoEa3uj6LMb+uOkNIIHM2Lep+E7KCAmZfP3tTAejuD0skHS90DAbV3rl70zkRH7PlbwIDAQABo1AwTjAdBgNVHQ4EFgQUUvQmIWw/43xDFkxbwnQ2D32oFLEwHwYDVR0jBBgwFoAUUvQmIWw/43xDFkxbwnQ2D32oFLEwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQ0FAAOBgQBs+6TosV25k/KIWTPGiNbCBBUTIEiy5SKUPx4e6WsTNSC91dlDlnwiV4Feag4v9RlanOLJI11XFibaw+SPQ1nUvpnfeKf4sU0jIzjoRHzFfd7VpirT5Uy5pmXZ4J01SGGP28PJ/wioxsnIDWe1HVJFbkMzlIBN3Mg/0pwwTJeZ0w== - - - - - - - MIICajCCAdOgAwIBAgIBADANBgkqhkiG9w0BAQ0FADBRMQswCQYDVQQGEwJzZzESMBAGA1UECAwJU2luZ2Fwb3JlMRAwDgYDVQQKDAdOVVNNb2RzMRwwGgYDVQQDDBNodHRwczovL251c21vZHMuY29tMCAXDTIxMDIwMTA4MzE0N1oYDzIxMjEwMTA4MDgzMTQ3WjBRMQswCQYDVQQGEwJzZzESMBAGA1UECAwJU2luZ2Fwb3JlMRAwDgYDVQQKDAdOVVNNb2RzMRwwGgYDVQQDDBNodHRwczovL251c21vZHMuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDsUyFzxVrM8jDE8nmb+SEwo64rKvVAxO37W/AXsGIih/2j2ijl+WyGqHN8uDcPZi5hkyFaJ4t2tfdWn1cK1HdUQ1IO2YdKNv3ZvotU1wPoEa3uj6LMb+uOkNIIHM2Lep+E7KCAmZfP3tTAejuD0skHS90DAbV3rl70zkRH7PlbwIDAQABo1AwTjAdBgNVHQ4EFgQUUvQmIWw/43xDFkxbwnQ2D32oFLEwHwYDVR0jBBgwFoAUUvQmIWw/43xDFkxbwnQ2D32oFLEwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQ0FAAOBgQBs+6TosV25k/KIWTPGiNbCBBUTIEiy5SKUPx4e6WsTNSC91dlDlnwiV4Feag4v9RlanOLJI11XFibaw+SPQ1nUvpnfeKf4sU0jIzjoRHzFfd7VpirT5Uy5pmXZ4J01SGGP28PJ/wioxsnIDWe1HVJFbkMzlIBN3Mg/0pwwTJeZ0w== - - - - urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified - - - diff --git a/backend/crates/nusmods-api/src/auth.rs b/backend/crates/nusmods-api/src/auth.rs index c967b5495d..3305a86b6c 100644 --- a/backend/crates/nusmods-api/src/auth.rs +++ b/backend/crates/nusmods-api/src/auth.rs @@ -86,7 +86,14 @@ async fn get_login_url(Query(query): Query) -> Result Router { Router::new() .route("/user", get(get_user))