From 9f7460973e5ff109490015e01edd72e826c4eea2 Mon Sep 17 00:00:00 2001 From: N08I40K Date: Sat, 22 Mar 2025 03:20:55 +0400 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=BE=D0=B4=D0=BA=D0=BB=D1=8E=D1=87?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BA=20Postgres=20=D0=B8=20=D1=82?= =?UTF-8?q?=D0=B5=D1=81=D1=82=D0=BE=D0=B2=D1=8B=D0=B9=20=D1=8D=D0=BD=D0=B4?= =?UTF-8?q?=D0=BF=D0=BE=D0=B8=D0=BD=D1=82=20=D0=B0=D0=B2=D1=82=D0=BE=D1=80?= =?UTF-8?q?=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 4 +- .idea/dataSources.xml | 12 + .idea/sqldialects.xml | 9 + Cargo.lock | 789 +++++++++++++++++- Cargo.toml | 5 +- diesel.toml | 9 + lib/schedule_parser/src/lib/lib.rs | 2 +- migrations/.keep | 0 .../down.sql | 6 + .../up.sql | 36 + .../down.sql | 1 + .../2025-03-21-211822_create_user_role/up.sql | 4 + .../2025-03-21-212111_create_users/down.sql | 1 + .../2025-03-21-212111_create_users/up.sql | 11 + .../2025-03-21-212723_create_fcm/down.sql | 1 + .../2025-03-21-212723_create_fcm/up.sql | 11 + src/database/mod.rs | 2 + src/database/models.rs | 26 + src/database/schema.rs | 38 + src/main.rs | 86 +- src/routes/auth/mod.rs | 2 + src/routes/auth/schema.rs | 56 ++ src/routes/auth/sign_in.rs | 26 + src/routes/mod.rs | 1 + 24 files changed, 1091 insertions(+), 47 deletions(-) create mode 100644 .idea/dataSources.xml create mode 100644 .idea/sqldialects.xml create mode 100644 diesel.toml create mode 100644 migrations/.keep create mode 100644 migrations/00000000000000_diesel_initial_setup/down.sql create mode 100644 migrations/00000000000000_diesel_initial_setup/up.sql create mode 100644 migrations/2025-03-21-211822_create_user_role/down.sql create mode 100644 migrations/2025-03-21-211822_create_user_role/up.sql create mode 100644 migrations/2025-03-21-212111_create_users/down.sql create mode 100644 migrations/2025-03-21-212111_create_users/up.sql create mode 100644 migrations/2025-03-21-212723_create_fcm/down.sql create mode 100644 migrations/2025-03-21-212723_create_fcm/up.sql create mode 100644 src/database/mod.rs create mode 100644 src/database/models.rs create mode 100644 src/database/schema.rs create mode 100644 src/routes/auth/mod.rs create mode 100644 src/routes/auth/schema.rs create mode 100644 src/routes/auth/sign_in.rs create mode 100644 src/routes/mod.rs diff --git a/.gitignore b/.gitignore index 3978cb6..b6bf0fa 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ /target .~*.xls schedule.json -teachers.json \ No newline at end of file +teachers.json + +.env* \ No newline at end of file diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml new file mode 100644 index 0000000..165053c --- /dev/null +++ b/.idea/dataSources.xml @@ -0,0 +1,12 @@ + + + + + postgresql + true + org.postgresql.Driver + jdbc:postgresql://localhost:5432/sp + $ProjectFileDir$ + + + \ No newline at end of file diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml new file mode 100644 index 0000000..da3341b --- /dev/null +++ b/.idea/sqldialects.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index d1cb14a..d5c15c9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,189 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "actix-codec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f7b0a21988c1bf877cf4759ef5ddaac04c1c9fe808c9142ecb78ba97d97a28a" +dependencies = [ + "bitflags", + "bytes", + "futures-core", + "futures-sink", + "memchr", + "pin-project-lite", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "actix-http" +version = "3.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa882656b67966045e4152c634051e70346939fced7117d5f0b52146a7c74c9" +dependencies = [ + "actix-codec", + "actix-rt", + "actix-service", + "actix-utils", + "base64", + "bitflags", + "brotli", + "bytes", + "bytestring", + "derive_more", + "encoding_rs", + "flate2", + "foldhash", + "futures-core", + "h2 0.3.26", + "http 0.2.12", + "httparse", + "httpdate", + "itoa", + "language-tags", + "local-channel", + "mime", + "percent-encoding", + "pin-project-lite", + "rand", + "sha1", + "smallvec", + "tokio", + "tokio-util", + "tracing", + "zstd", +] + +[[package]] +name = "actix-macros" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "actix-router" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13d324164c51f63867b57e73ba5936ea151b8a41a1d23d1031eeb9f70d0236f8" +dependencies = [ + "bytestring", + "cfg-if", + "http 0.2.12", + "regex", + "regex-lite", + "serde", + "tracing", +] + +[[package]] +name = "actix-rt" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24eda4e2a6e042aa4e55ac438a2ae052d3b5da0ecf83d7411e1a368946925208" +dependencies = [ + "futures-core", + "tokio", +] + +[[package]] +name = "actix-server" +version = "2.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6398974fd4284f4768af07965701efbbb5fdc0616bff20cade1bb14b77675e24" +dependencies = [ + "actix-rt", + "actix-service", + "actix-utils", + "futures-core", + "futures-util", + "mio", + "socket2", + "tokio", + "tracing", +] + +[[package]] +name = "actix-service" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e46f36bf0e5af44bdc4bdb36fbbd421aa98c79a9bce724e1edeb3894e10dc7f" +dependencies = [ + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "actix-utils" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88a1dcdff1466e3c2488e1cb5c36a71822750ad43839937f85d2f4d9f8b705d8" +dependencies = [ + "local-waker", + "pin-project-lite", +] + +[[package]] +name = "actix-web" +version = "4.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2e3b15b3dc6c6ed996e4032389e9849d4ab002b1e92fbfe85b5f307d1479b4d" +dependencies = [ + "actix-codec", + "actix-http", + "actix-macros", + "actix-router", + "actix-rt", + "actix-server", + "actix-service", + "actix-utils", + "actix-web-codegen", + "bytes", + "bytestring", + "cfg-if", + "cookie", + "derive_more", + "encoding_rs", + "foldhash", + "futures-core", + "futures-util", + "impl-more", + "itoa", + "language-tags", + "log", + "mime", + "once_cell", + "pin-project-lite", + "regex", + "regex-lite", + "serde", + "serde_json", + "serde_urlencoded", + "smallvec", + "socket2", + "time", + "tracing", + "url", +] + +[[package]] +name = "actix-web-codegen" +version = "4.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f591380e2e68490b5dfaf1dd1aa0ebe78d84ba7067078512b4ea6e4492d622b8" +dependencies = [ + "actix-router", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "addr2line" version = "0.24.2" @@ -26,6 +209,21 @@ dependencies = [ "memchr", ] +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + [[package]] name = "android-tzdata" version = "0.1.1" @@ -101,6 +299,36 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "brotli" +version = "7.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc97b8f16f944bba54f0433f07e30be199b6dc2bd25937444bbad560bcea29bd" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "4.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74fa05ad7d803d413eb8380983b092cbbaf9a85f151b871360e7b00cd7060b37" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + [[package]] name = "bumpalo" version = "3.17.0" @@ -119,6 +347,15 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +[[package]] +name = "bytestring" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e465647ae23b2823b0753f50decb2d5a86d2bb2cac04788fafd1f80e45378e5f" +dependencies = [ + "bytes", +] + [[package]] name = "calamine" version = "0.26.1" @@ -146,6 +383,8 @@ version = "1.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" dependencies = [ + "jobserver", + "libc", "shlex", ] @@ -231,6 +470,17 @@ dependencies = [ "encoding_rs", ] +[[package]] +name = "cookie" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" +dependencies = [ + "percent-encoding", + "time", + "version_check", +] + [[package]] name = "core-foundation" version = "0.9.4" @@ -247,6 +497,15 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + [[package]] name = "crc32fast" version = "1.4.2" @@ -323,6 +582,60 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "darling" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +dependencies = [ + "darling_core", + "quote", + "syn", +] + +[[package]] +name = "deranged" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +dependencies = [ + "powerfmt", +] + [[package]] name = "derive_arbitrary" version = "1.4.1" @@ -334,6 +647,83 @@ dependencies = [ "syn", ] +[[package]] +name = "derive_more" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "unicode-xid", +] + +[[package]] +name = "diesel" +version = "2.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "470eb10efc8646313634c99bb1593f402a6434cbd86e266770c6e39219adb86a" +dependencies = [ + "bitflags", + "byteorder", + "diesel_derives", + "itoa", + "pq-sys", +] + +[[package]] +name = "diesel-derive-enum" +version = "2.2.0" +source = "git+https://github.com/Havunen/diesel-derive-enum.git#e0e57dad5508863da9a43dd35953fa92819261d7" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "diesel_derives" +version = "2.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a93958254b70bea63b4187ff73d10180599d9d8d177071b7f91e6da4e0c0ad55" +dependencies = [ + "diesel_table_macro_syntax", + "dsl_auto_type", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "diesel_table_macro_syntax" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "209c735641a413bc68c4923a9d6ad4bcb3ca306b794edaa7eb0b3228a99ffb25" +dependencies = [ + "syn", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + [[package]] name = "displaydoc" version = "0.2.5" @@ -345,6 +735,26 @@ dependencies = [ "syn", ] +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + +[[package]] +name = "dsl_auto_type" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139ae9aca7527f85f26dd76483eb38533fd84bd571065da1739656ef71c5ff5b" +dependencies = [ + "darling", + "either", + "heck", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "either" version = "1.15.0" @@ -398,6 +808,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + [[package]] name = "foreign-types" version = "0.3.2" @@ -470,6 +886,16 @@ dependencies = [ "thread_local", ] +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "getrandom" version = "0.2.15" @@ -499,6 +925,25 @@ version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.12", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "h2" version = "0.4.8" @@ -510,7 +955,7 @@ dependencies = [ "fnv", "futures-core", "futures-sink", - "http", + "http 1.3.1", "indexmap", "slab", "tokio", @@ -534,12 +979,29 @@ version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbd780fe5cc30f81464441920d82ac8740e2e46b29a6fad543ddd075229ce37e" +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http" version = "1.3.1" @@ -558,7 +1020,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http", + "http 1.3.1", ] [[package]] @@ -569,7 +1031,7 @@ checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", "futures-core", - "http", + "http 1.3.1", "http-body", "pin-project-lite", ] @@ -580,6 +1042,12 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + [[package]] name = "hyper" version = "1.6.0" @@ -589,8 +1057,8 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "h2", - "http", + "h2 0.4.8", + "http 1.3.1", "http-body", "httparse", "itoa", @@ -607,7 +1075,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" dependencies = [ "futures-util", - "http", + "http 1.3.1", "hyper", "hyper-util", "rustls", @@ -642,7 +1110,7 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "http", + "http 1.3.1", "http-body", "hyper", "pin-project-lite", @@ -793,6 +1261,12 @@ dependencies = [ "syn", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" version = "1.0.3" @@ -814,6 +1288,12 @@ dependencies = [ "icu_properties", ] +[[package]] +name = "impl-more" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a5a9a0ff0086c7a148acb942baaabeadf9504d10400b5a05645853729b9cd2" + [[package]] name = "indexmap" version = "2.8.0" @@ -856,6 +1336,15 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] + [[package]] name = "js-sys" version = "0.3.77" @@ -866,6 +1355,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "language-tags" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" + [[package]] name = "libc" version = "0.2.171" @@ -884,6 +1379,33 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" +[[package]] +name = "local-channel" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6cbc85e69b8df4b8bb8b89ec634e7189099cea8927a276b7384ce5488e53ec8" +dependencies = [ + "futures-core", + "futures-sink", + "local-waker", +] + +[[package]] +name = "local-waker" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d873d7c67ce09b42110d801813efbc9364414e356be9935700d368351657487" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + [[package]] name = "lockfree-object-pool" version = "0.1.6" @@ -924,6 +1446,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ "libc", + "log", "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.52.0", ] @@ -945,6 +1468,12 @@ dependencies = [ "tempfile", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-traits" version = "0.2.19" @@ -1019,6 +1548,29 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.6", +] + [[package]] name = "percent-encoding" version = "2.3.1" @@ -1071,6 +1623,31 @@ dependencies = [ "plotters-backend", ] +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "pq-sys" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b51d65ebe1cb1f40641b15abae017fed35ccdda46e3dab1ff8768f625a3222" +dependencies = [ + "libc", + "vcpkg", +] + [[package]] name = "proc-macro2" version = "1.0.94" @@ -1105,6 +1682,36 @@ version = "5.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" +[[package]] +name = "rand" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" +dependencies = [ + "rand_chacha", + "rand_core", + "zerocopy", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.2", +] + [[package]] name = "rayon" version = "1.10.0" @@ -1125,6 +1732,15 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "redox_syscall" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" +dependencies = [ + "bitflags", +] + [[package]] name = "regex" version = "1.11.1" @@ -1148,6 +1764,12 @@ dependencies = [ "regex-syntax", ] +[[package]] +name = "regex-lite" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a" + [[package]] name = "regex-syntax" version = "0.8.5" @@ -1165,8 +1787,8 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "h2", - "http", + "h2 0.4.8", + "http 1.3.1", "http-body", "http-body-util", "hyper", @@ -1304,11 +1926,14 @@ dependencies = [ name = "schedule-parser-rusted" version = "0.3.0" dependencies = [ + "actix-web", "chrono", + "diesel", + "diesel-derive-enum", + "dotenvy", "reqwest", "schedule_parser", "serde", - "serde_json", "tokio", ] @@ -1325,6 +1950,12 @@ dependencies = [ "serde_repr", ] +[[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.11.1" @@ -1403,12 +2034,32 @@ dependencies = [ "serde", ] +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "shlex" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + [[package]] name = "simd-adler32" version = "0.3.7" @@ -1446,6 +2097,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "subtle" version = "2.6.1" @@ -1547,6 +2204,37 @@ dependencies = [ "once_cell", ] +[[package]] +name = "time" +version = "0.3.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d9c75b47bdff86fa3334a3db91356b8d7d86a9b839dab7d0bdc5c3d3a077618" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" + +[[package]] +name = "time-macros" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29aa485584182073ed57fd5004aa09c371f021325014694e432313345865fd04" +dependencies = [ + "num-conv", + "time-core", +] + [[package]] name = "tinystr" version = "0.7.6" @@ -1577,7 +2265,9 @@ dependencies = [ "bytes", "libc", "mio", + "parking_lot", "pin-project-lite", + "signal-hook-registry", "socket2", "tokio-macros", "windows-sys 0.52.0", @@ -1660,10 +2350,23 @@ version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ + "log", "pin-project-lite", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tracing-core" version = "0.1.33" @@ -1679,12 +2382,24 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +[[package]] +name = "typenum" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" + [[package]] name = "unicode-ident" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + [[package]] name = "untrusted" version = "0.9.0" @@ -1720,6 +2435,12 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + [[package]] name = "walkdir" version = "2.5.0" @@ -2079,6 +2800,26 @@ dependencies = [ "synstructure", ] +[[package]] +name = "zerocopy" +version = "0.8.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "zerofrom" version = "0.1.6" @@ -2158,3 +2899,31 @@ dependencies = [ "once_cell", "simd-adler32", ] + +[[package]] +name = "zstd" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.15+zstd.1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb81183ddd97d0c74cedf1d50d85c8d08c1b8b68ee863bdee9e706eedba1a237" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/Cargo.toml b/Cargo.toml index 65275d1..2094a0c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,9 +8,12 @@ edition = "2024" publish = false [dependencies] +diesel = { version = "2.2.8", features = ["postgres"] } +diesel-derive-enum = { git = "https://github.com/Havunen/diesel-derive-enum.git", features = ["postgres"] } +dotenvy = "0.15.7" serde = { version = "1.0.219", features = ["derive"] } -serde_json = "1.0.140" schedule_parser = { path = "./lib/schedule_parser" } chrono = "0.4.40" reqwest = "0.12.15" tokio = { version = "1.44.1", features = ["macros", "rt-multi-thread"] } +actix-web = "4.10.2" diff --git a/diesel.toml b/diesel.toml new file mode 100644 index 0000000..803c125 --- /dev/null +++ b/diesel.toml @@ -0,0 +1,9 @@ +# For documentation on how to configure this file, +# see https://diesel.rs/guides/configuring-diesel-cli + +[print_schema] +file = "src/database/schema.rs" +custom_type_derives = ["diesel::query_builder::QueryId", "Clone"] + +[migrations_directory] +dir = "./migrations" diff --git a/lib/schedule_parser/src/lib/lib.rs b/lib/schedule_parser/src/lib/lib.rs index 88fb2e7..c30bb7b 100644 --- a/lib/schedule_parser/src/lib/lib.rs +++ b/lib/schedule_parser/src/lib/lib.rs @@ -10,7 +10,7 @@ use std::collections::HashMap; use std::io::Cursor; use std::sync::LazyLock; -mod schema; +pub mod schema; struct InternalId { /** diff --git a/migrations/.keep b/migrations/.keep new file mode 100644 index 0000000..e69de29 diff --git a/migrations/00000000000000_diesel_initial_setup/down.sql b/migrations/00000000000000_diesel_initial_setup/down.sql new file mode 100644 index 0000000..a9f5260 --- /dev/null +++ b/migrations/00000000000000_diesel_initial_setup/down.sql @@ -0,0 +1,6 @@ +-- This file was automatically created by Diesel to setup helper functions +-- and other internal bookkeeping. This file is safe to edit, any future +-- changes will be added to existing projects as new migrations. + +DROP FUNCTION IF EXISTS diesel_manage_updated_at(_tbl regclass); +DROP FUNCTION IF EXISTS diesel_set_updated_at(); diff --git a/migrations/00000000000000_diesel_initial_setup/up.sql b/migrations/00000000000000_diesel_initial_setup/up.sql new file mode 100644 index 0000000..d68895b --- /dev/null +++ b/migrations/00000000000000_diesel_initial_setup/up.sql @@ -0,0 +1,36 @@ +-- This file was automatically created by Diesel to setup helper functions +-- and other internal bookkeeping. This file is safe to edit, any future +-- changes will be added to existing projects as new migrations. + + + + +-- Sets up a trigger for the given table to automatically set a column called +-- `updated_at` whenever the row is modified (unless `updated_at` was included +-- in the modified columns) +-- +-- # Example +-- +-- ```sql +-- CREATE TABLE users (id SERIAL PRIMARY KEY, updated_at TIMESTAMP NOT NULL DEFAULT NOW()); +-- +-- SELECT diesel_manage_updated_at('users'); +-- ``` +CREATE OR REPLACE FUNCTION diesel_manage_updated_at(_tbl regclass) RETURNS VOID AS $$ +BEGIN + EXECUTE format('CREATE TRIGGER set_updated_at BEFORE UPDATE ON %s + FOR EACH ROW EXECUTE PROCEDURE diesel_set_updated_at()', _tbl); +END; +$$ LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION diesel_set_updated_at() RETURNS trigger AS $$ +BEGIN + IF ( + NEW IS DISTINCT FROM OLD AND + NEW.updated_at IS NOT DISTINCT FROM OLD.updated_at + ) THEN + NEW.updated_at := current_timestamp; + END IF; + RETURN NEW; +END; +$$ LANGUAGE plpgsql; diff --git a/migrations/2025-03-21-211822_create_user_role/down.sql b/migrations/2025-03-21-211822_create_user_role/down.sql new file mode 100644 index 0000000..8df4f0f --- /dev/null +++ b/migrations/2025-03-21-211822_create_user_role/down.sql @@ -0,0 +1 @@ +DROP TYPE user_role; \ No newline at end of file diff --git a/migrations/2025-03-21-211822_create_user_role/up.sql b/migrations/2025-03-21-211822_create_user_role/up.sql new file mode 100644 index 0000000..889ca7a --- /dev/null +++ b/migrations/2025-03-21-211822_create_user_role/up.sql @@ -0,0 +1,4 @@ +CREATE TYPE user_role AS ENUM ( + 'STUDENT', + 'TEACHER', + 'ADMIN'); \ No newline at end of file diff --git a/migrations/2025-03-21-212111_create_users/down.sql b/migrations/2025-03-21-212111_create_users/down.sql new file mode 100644 index 0000000..441087a --- /dev/null +++ b/migrations/2025-03-21-212111_create_users/down.sql @@ -0,0 +1 @@ +DROP TABLE users; \ No newline at end of file diff --git a/migrations/2025-03-21-212111_create_users/up.sql b/migrations/2025-03-21-212111_create_users/up.sql new file mode 100644 index 0000000..ca1ac7e --- /dev/null +++ b/migrations/2025-03-21-212111_create_users/up.sql @@ -0,0 +1,11 @@ +CREATE TABLE users +( + id text PRIMARY KEY NOT NULL, + username text UNIQUE NOT NULL, + "password" text NOT NULL, + vk_id int4 NULL, + access_token text UNIQUE NOT NULL, + "group" text NOT NULL, + role user_role NOT NULL, + version text NOT NULL +); \ No newline at end of file diff --git a/migrations/2025-03-21-212723_create_fcm/down.sql b/migrations/2025-03-21-212723_create_fcm/down.sql new file mode 100644 index 0000000..82e5923 --- /dev/null +++ b/migrations/2025-03-21-212723_create_fcm/down.sql @@ -0,0 +1 @@ +DROP TABLE fcm; \ No newline at end of file diff --git a/migrations/2025-03-21-212723_create_fcm/up.sql b/migrations/2025-03-21-212723_create_fcm/up.sql new file mode 100644 index 0000000..77dd7da --- /dev/null +++ b/migrations/2025-03-21-212723_create_fcm/up.sql @@ -0,0 +1,11 @@ +CREATE TABLE fcm +( + user_id text PRIMARY KEY NOT NULL, + token text NOT NULL, + topics text[] NULL +); + +CREATE UNIQUE INDEX fcm_user_id_key ON fcm USING btree (user_id); + +ALTER TABLE fcm + ADD CONSTRAINT fcm_user_id_fkey FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE RESTRICT ON UPDATE CASCADE; \ No newline at end of file diff --git a/src/database/mod.rs b/src/database/mod.rs new file mode 100644 index 0000000..2e2cb1f --- /dev/null +++ b/src/database/mod.rs @@ -0,0 +1,2 @@ +pub mod schema; +pub mod models; diff --git a/src/database/models.rs b/src/database/models.rs new file mode 100644 index 0000000..18ab713 --- /dev/null +++ b/src/database/models.rs @@ -0,0 +1,26 @@ +use diesel::prelude::*; +use serde::Serialize; + +#[derive(diesel_derive_enum::DbEnum, Serialize, Debug)] +#[ExistingTypePath = "crate::database::schema::sql_types::UserRole"] +#[DbValueStyle = "UPPERCASE"] +#[serde(rename_all = "UPPERCASE")] +pub enum UserRole { + Student, + Teacher, + Admin, +} + +#[derive(Queryable, Selectable, Serialize)] +#[diesel(table_name = crate::database::schema::users)] +#[diesel(check_for_backend(diesel::pg::Pg))] +pub struct User { + pub id: String, + pub username: String, + pub password: String, + pub vk_id: Option, + pub access_token: String, + pub group: String, + pub role: UserRole, + pub version: String, +} diff --git a/src/database/schema.rs b/src/database/schema.rs new file mode 100644 index 0000000..ae691df --- /dev/null +++ b/src/database/schema.rs @@ -0,0 +1,38 @@ +// @generated automatically by Diesel CLI. + +pub mod sql_types { + #[derive(diesel::query_builder::QueryId, Clone, diesel::sql_types::SqlType)] + #[diesel(postgres_type(name = "user_role"))] + pub struct UserRole; +} + +diesel::table! { + fcm (user_id) { + user_id -> Text, + token -> Text, + topics -> Nullable>>, + } +} + +diesel::table! { + use diesel::sql_types::*; + use super::sql_types::UserRole; + + users (id) { + id -> Text, + username -> Text, + password -> Text, + vk_id -> Nullable, + access_token -> Text, + group -> Text, + role -> UserRole, + version -> Text, + } +} + +diesel::joinable!(fcm -> users (user_id)); + +diesel::allow_tables_to_appear_in_same_query!( + fcm, + users, +); diff --git a/src/main.rs b/src/main.rs index 9803a4e..c453f95 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,39 +1,57 @@ +use crate::routes::auth::sign_in::sign_in; use crate::xls_downloader::basic_impl::BasicXlsDownloader; -use crate::xls_downloader::interface::XLSDownloader; -use schedule_parser::parse_xls; -use std::{env, fs}; +use actix_web::{web, App, HttpServer}; +use chrono::{DateTime, Utc}; +use diesel::{Connection, PgConnection}; +use dotenvy::dotenv; +use schedule_parser::schema::ScheduleEntity; +use std::collections::HashMap; +use std::sync::Mutex; +use std::env; +mod database; +mod routes; mod xls_downloader; -#[tokio::main] -async fn main() { - let args: Vec = env::args().collect(); - assert_ne!(args.len(), 1); - - let mut downloader = BasicXlsDownloader::new(); - - downloader - .set_url(args[1].to_string()) - .await - .expect("Failed to set url"); - - let fetch_res = downloader.fetch(false).await.expect("Failed to fetch xls"); - - let (teachers, groups) = parse_xls(fetch_res.data.as_ref().unwrap()); - - fs::write( - "./schedule.json", - serde_json::to_string_pretty(&groups) - .expect("Failed to serialize schedule") - .as_bytes(), - ) - .expect("Failed to write schedule"); - - fs::write( - "./teachers.json", - serde_json::to_string_pretty(&teachers) - .expect("Failed to serialize teachers schedule") - .as_bytes(), - ) - .expect("Failed to write teachers schedule"); +pub struct AppState { + downloader: Mutex, + schedule: Mutex< + Option<( + String, + DateTime, + ( + HashMap, + HashMap, + ), + )>, + >, + database: Mutex, +} + +#[actix_web::main] +async fn main() { + dotenv().ok(); + + let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set"); + + let data = web::Data::new(AppState { + downloader: Mutex::new(BasicXlsDownloader::new()), + schedule: Mutex::new(None), + database: Mutex::new( + PgConnection::establish(&database_url) + .unwrap_or_else(|_| panic!("Error connecting to {}", database_url)), + ), + }); + + HttpServer::new(move || { + let schedule_scope = web::scope("/auth").service(sign_in); + let api_scope = web::scope("/api/v1").service(schedule_scope); + + App::new().app_data(data.clone()).service(api_scope) + }) + .bind(("127.0.0.1", 8080)) + .unwrap() + .run() + .await + .unwrap(); } diff --git a/src/routes/auth/mod.rs b/src/routes/auth/mod.rs new file mode 100644 index 0000000..523aba4 --- /dev/null +++ b/src/routes/auth/mod.rs @@ -0,0 +1,2 @@ +pub mod sign_in; +mod schema; \ No newline at end of file diff --git a/src/routes/auth/schema.rs b/src/routes/auth/schema.rs new file mode 100644 index 0000000..d881008 --- /dev/null +++ b/src/routes/auth/schema.rs @@ -0,0 +1,56 @@ +use crate::database::models::User; +use serde::{Deserialize, Serialize, Serializer}; + +#[derive(Deserialize)] +pub struct SignInDto { + pub username: String, + pub password: String, +} + +pub struct SignInResult(Result); + +#[derive(Serialize)] +#[serde(rename_all = "camelCase")] +pub struct SignInOk { + id: String, + access_token: String, + group: String, +} + +#[derive(Serialize)] +pub struct SignInErr { + code: SignInErrCode, +} + +#[derive(Serialize)] +#[serde(rename_all = "SCREAMING_SNAKE_CASE")] +pub enum SignInErrCode { + IncorrectCredentials, + InvalidVkAccessToken, +} + +impl SignInResult { + pub fn ok(user: &User) -> Self { + Self(Ok(SignInOk { + id: user.id.clone(), + access_token: user.access_token.clone(), + group: user.group.clone(), + })) + } + + pub fn err(code: SignInErrCode) -> SignInResult { + Self(Err(SignInErr { code })) + } +} + +impl Serialize for SignInResult { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match &self.0 { + Ok(ok) => serializer.serialize_some(&ok), + Err(err) => serializer.serialize_some(&err), + } + } +} diff --git a/src/routes/auth/sign_in.rs b/src/routes/auth/sign_in.rs new file mode 100644 index 0000000..83d953d --- /dev/null +++ b/src/routes/auth/sign_in.rs @@ -0,0 +1,26 @@ +use crate::database::models::User; +use crate::routes::auth::schema::SignInErrCode::IncorrectCredentials; +use crate::routes::auth::schema::{SignInDto, SignInResult}; +use crate::AppState; +use actix_web::{post, web}; +use diesel::{ExpressionMethods, QueryDsl, RunQueryDsl, SelectableHelper}; +use std::ops::DerefMut; +use web::Json; + +#[post("/sign-in")] +pub async fn sign_in(data: Json, app_state: web::Data) -> Json { + use crate::database::schema::users::dsl::*; + + match { + let mut lock = app_state.database.lock().unwrap(); + let connection = lock.deref_mut(); + + users + .filter(username.eq(data.username.clone())) + .select(User::as_select()) + .first(connection) + } { + Ok(user) => Json(SignInResult::ok(&user)), + Err(_) => Json(SignInResult::err(IncorrectCredentials)), + } +} diff --git a/src/routes/mod.rs b/src/routes/mod.rs new file mode 100644 index 0000000..5696e21 --- /dev/null +++ b/src/routes/mod.rs @@ -0,0 +1 @@ +pub mod auth; \ No newline at end of file