From 9d8ba14649fa5bf5ba17c040e17842babbb361e7 Mon Sep 17 00:00:00 2001 From: shenghui0779 Date: Tue, 5 Nov 2024 18:59:42 +0800 Subject: [PATCH] hash password with bcrypt --- Cargo.lock | 402 ++++++++++++++++++++++++++++++----- Cargo.toml | 1 + demo_rs.sql | 8 +- src/app/api/account.rs | 2 +- src/app/api/auth.rs | 2 +- src/app/api/project.rs | 2 +- src/app/middleware/mod.rs | 5 +- src/app/model/account.rs | 2 - src/app/service/account.rs | 26 +-- src/app/service/auth.rs | 21 +- src/app/service/project.rs | 12 +- src/shared/middleware/log.rs | 2 +- src/shared/util/identity.rs | 20 +- src/shared/util/mutex.rs | 4 +- 14 files changed, 403 insertions(+), 106 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c8d3167..150382a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -113,9 +113,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.17" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", @@ -128,9 +128,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8365de52b16c035ff4fcafe0092ba9390540e3e352870ac09933bebcaa2c8c56" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" @@ -162,9 +162,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.91" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c042108f3ed77fd83760a5fd79b53be043192bb3b9dba91d8c574c0ada7850c8" +checksum = "74f37166d7d48a0284b99dd824694c26119c700b53bf0d1540cdb147dbdaaf13" [[package]] name = "arc-swap" @@ -203,7 +203,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -214,7 +214,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -271,6 +271,19 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +[[package]] +name = "bcrypt" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e65938ed058ef47d92cf8b346cc76ef48984572ade631927e9937b5ffc7662c7" +dependencies = [ + "base64 0.22.1", + "blowfish", + "getrandom", + "subtle", + "zeroize", +] + [[package]] name = "bigdecimal" version = "0.4.6" @@ -315,6 +328,16 @@ dependencies = [ "generic-array", ] +[[package]] +name = "blowfish" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e412e2cd0f2b2d93e02543ceae7917b3c70331573df19ee046bcbc35e45e87d7" +dependencies = [ + "byteorder", + "cipher", +] + [[package]] name = "borsh" version = "1.5.1" @@ -335,7 +358,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", "syn_derive", ] @@ -381,9 +404,9 @@ checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" [[package]] name = "cc" -version = "1.1.31" +version = "1.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" +checksum = "67b9470d453346108f93a59222a9a1a5724db32d0a4727b7ab7ace4b4d822dc9" dependencies = [ "shlex", ] @@ -454,7 +477,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -705,6 +728,17 @@ dependencies = [ "subtle", ] +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "dlv-list" version = "0.5.2" @@ -755,7 +789,7 @@ checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -916,7 +950,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -1034,9 +1068,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" [[package]] name = "hashlink" @@ -1286,6 +1320,124 @@ dependencies = [ "cc", ] +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "idna" version = "0.4.0" @@ -1298,12 +1450,23 @@ dependencies = [ [[package]] name = "idna" -version = "0.5.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", ] [[package]] @@ -1319,7 +1482,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.15.0", + "hashbrown 0.15.1", ] [[package]] @@ -1330,7 +1493,7 @@ checksum = "0122b7114117e64a63ac49f752a5ca4624d534c7b1c7de796ac196381cd2d947" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -1442,6 +1605,12 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "litemap" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" + [[package]] name = "lock_api" version = "0.4.12" @@ -1746,7 +1915,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -1818,7 +1987,7 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -1924,7 +2093,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -1955,7 +2124,7 @@ checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -2082,7 +2251,7 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -2102,7 +2271,7 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", "version_check", "yansi", ] @@ -2438,9 +2607,9 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustix" -version = "0.38.38" +version = "0.38.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa260229e6538e52293eeb577aabd09945a09d6d9cc0fc550ed7529056c2e32a" +checksum = "375116bee2be9ed569afe2154ea6a99dfdffd257f533f187498c2a8f5feaf4ee" dependencies = [ "bitflags", "errno", @@ -2578,7 +2747,7 @@ checksum = "6f568f3050f43e828615121a27ae38450987d3d6aa8ac072dce6d3171df6b383" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -2636,7 +2805,7 @@ dependencies = [ "quote", "regex", "salvo-serde-util", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -2673,14 +2842,14 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] name = "sea-orm" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c4872675cc5d5d399a2a202c60f3a393ec8d3f3307c36adb166517f348e4db5" +checksum = "d5680a8b686985116607ef5f5af2b1f9e1cc2c228330e93101816a0baa279afa" dependencies = [ "async-stream", "async-trait", @@ -2706,15 +2875,15 @@ dependencies = [ [[package]] name = "sea-orm-macros" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85f714906b72e7265c0b2077d0ad8f235dabebda513c92f1326d5d40cef0dd01" +checksum = "3a239e3bb1b566ad4ec2654d0d193d6ceddfd733487edc9c21a64d214c773910" dependencies = [ "heck 0.4.1", "proc-macro2", "quote", "sea-bae", - "syn 2.0.85", + "syn 2.0.87", "unicode-ident", ] @@ -2808,7 +2977,7 @@ checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -3051,7 +3220,7 @@ dependencies = [ "quote", "sqlx-core", "sqlx-macros-core", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -3074,7 +3243,7 @@ dependencies = [ "sqlx-mysql", "sqlx-postgres", "sqlx-sqlite", - "syn 2.0.85", + "syn 2.0.87", "tempfile", "tokio", "url", @@ -3197,6 +3366,12 @@ dependencies = [ "uuid", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "static_assertions" version = "1.1.0" @@ -3245,9 +3420,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.85" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", @@ -3263,7 +3438,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -3275,6 +3450,17 @@ dependencies = [ "futures-core", ] +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "system-configuration" version = "0.6.1" @@ -3317,22 +3503,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.65" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5" +checksum = "02dd99dc800bbb97186339685293e1cc5d9df1f8fae2d0aecd9ff1c77efea892" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.65" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" +checksum = "a7c61ec9a6f64d2793d8a45faba21efbe3ced62a886d44c36a009b2b519b4c7e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -3387,6 +3573,16 @@ dependencies = [ "crunchy", ] +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tinyvec" version = "1.8.0" @@ -3428,7 +3624,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -3548,7 +3744,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -3686,15 +3882,27 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.2" +version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +checksum = "8d157f1b96d14500ffdc1f10ba712e780825526c03d9a49b4d0324b0d9113ada" dependencies = [ "form_urlencoded", - "idna 0.5.0", + "idna 1.0.3", "percent-encoding", ] +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" version = "0.2.2" @@ -3813,7 +4021,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", "wasm-bindgen-shared", ] @@ -3847,7 +4055,7 @@ checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4128,6 +4336,18 @@ dependencies = [ "memchr", ] +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + [[package]] name = "wyz" version = "0.5.1" @@ -4166,6 +4386,7 @@ version = "1.3.0" dependencies = [ "anyhow", "base64 0.22.1", + "bcrypt", "clap", "config", "const-hex", @@ -4200,6 +4421,30 @@ dependencies = [ "validator", ] +[[package]] +name = "yoke" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", + "synstructure", +] + [[package]] name = "zerocopy" version = "0.7.35" @@ -4218,7 +4463,28 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", +] + +[[package]] +name = "zerofrom" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", + "synstructure", ] [[package]] @@ -4226,3 +4492,25 @@ name = "zeroize" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] diff --git a/Cargo.toml b/Cargo.toml index be95c16..b0365af 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,7 @@ sha1 = "0.10" sha2 = "0.10" hmac = "0.12" base64 = "0.22" +bcrypt = "0.15" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" config = "0.14" diff --git a/demo_rs.sql b/demo_rs.sql index 5cfb0f1..0983544 100644 --- a/demo_rs.sql +++ b/demo_rs.sql @@ -34,10 +34,8 @@ DROP TABLE IF EXISTS `account`; CREATE TABLE `account` ( `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '自增ID', `username` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT '' COMMENT '用户名称', - `password` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT '' COMMENT '用户密码', - `salt` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT '' COMMENT '加密盐', + `password` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT '' COMMENT '用户密码', `role` tinyint NOT NULL DEFAULT '0' COMMENT '角色:1 - 普通;2 - 管理员', - `realname` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT '' COMMENT '真实姓名', `login_at` bigint NOT NULL DEFAULT '0' COMMENT '最近一次登录时间', `login_token` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT '' COMMENT '当前登录的token', `created_at` bigint NOT NULL DEFAULT '0' COMMENT '创建时间', @@ -65,8 +63,8 @@ CREATE TABLE `project` ( LOCK TABLES `account` WRITE; TRUNCATE `account`; -INSERT INTO `account` (`id`, `username`, `password`, `salt`, `role`, `realname`, `login_at`, `login_token`, `created_at`, `updated_at`) VALUES - (1,'admin','e03dcdf34a257041b36bd77132130fdc','LCV8xdTcqmkhA$ze',2,'Administrator',1675941517,'cc3e49577201323b0010815f2485acd9',1675941476,1675941517); +INSERT INTO `account` (`id`, `username`, `password`, `role`, `login_at`, `login_token`, `created_at`, `updated_at`) VALUES + (1,'admin','$2b$12$6IazZqBcVoaWonrRYgXdGO.vqVI9MgkNzxTBZwCTkjlJAf8labC7O',2,0,'',1675941476,1675941517); UNLOCK TABLES; diff --git a/src/app/api/account.rs b/src/app/api/account.rs index b38e3cc..6dc37de 100644 --- a/src/app/api/account.rs +++ b/src/app/api/account.rs @@ -14,7 +14,7 @@ use crate::app::service::{ #[handler] pub async fn create(req: &mut Request) -> ApiResult<()> { let params = req.parse_json::().await.map_err(|e| { - tracing::error!(error = ?e, "Error req.parse_json"); + tracing::error!(err = ?e, "req.parse_json"); Code::ErrParams(Some("参数解析出错".to_string())) })?; if let Err(e) = params.validate() { diff --git a/src/app/api/auth.rs b/src/app/api/auth.rs index cb1b956..9ae4161 100644 --- a/src/app/api/auth.rs +++ b/src/app/api/auth.rs @@ -14,7 +14,7 @@ use crate::app::service::{ #[handler] pub async fn login(req: &mut Request) -> ApiResult { let params = req.parse_json::().await.map_err(|e| { - tracing::error!(error = ?e, "Error req.parse_json"); + tracing::error!(err = ?e, "req.parse_json"); Code::ErrParams(Some("参数解析出错".to_string())) })?; if let Err(e) = params.validate() { diff --git a/src/app/api/project.rs b/src/app/api/project.rs index 5964c48..3ea970e 100644 --- a/src/app/api/project.rs +++ b/src/app/api/project.rs @@ -14,7 +14,7 @@ use crate::app::service::{ #[handler] pub async fn create(req: &mut Request) -> ApiResult<()> { let params = req.parse_json::().await.map_err(|e| { - tracing::error!(error = ?e, "Error req.parse_json"); + tracing::error!(err = ?e, "req.parse_json"); Code::ErrParams(Some("参数解析出错".to_string())) })?; if let Err(e) = params.validate() { diff --git a/src/app/middleware/mod.rs b/src/app/middleware/mod.rs index 3ae1769..232d2a3 100644 --- a/src/app/middleware/mod.rs +++ b/src/app/middleware/mod.rs @@ -15,7 +15,10 @@ pub async fn auth_check(identity: &Identity) -> Result<()> { match ret { None => return Err(anyhow!("授权账号不存在")), Some(v) => { - if v.login_token.is_empty() || !identity.match_token(v.login_token) { + if v.login_token.is_empty() + || !identity.match_token(v.login_token) + || identity.is_expired() + { return Err(anyhow!("授权已失效")); } } diff --git a/src/app/model/account.rs b/src/app/model/account.rs index 299b1cc..d943c08 100644 --- a/src/app/model/account.rs +++ b/src/app/model/account.rs @@ -8,9 +8,7 @@ pub struct Model { #[sea_orm(unique)] pub username: String, pub password: String, - pub salt: String, pub role: i8, - pub realname: String, pub login_at: i64, pub login_token: String, pub created_at: i64, diff --git a/src/app/service/account.rs b/src/app/service/account.rs index fa7825c..37e752d 100644 --- a/src/app/service/account.rs +++ b/src/app/service/account.rs @@ -6,7 +6,6 @@ use serde::{Deserialize, Serialize}; use validator::Validate; use crate::shared::core::db; -use crate::shared::crypto::hash; use crate::shared::result::code::Code; use crate::shared::result::{reply, ApiResult}; use crate::shared::util::{helper, xtime}; @@ -19,8 +18,6 @@ pub struct ReqCreate { pub username: String, #[validate(length(min = 1, message = "密码必填"))] pub password: String, - #[validate(length(min = 1, message = "实名必填"))] - pub realname: String, } pub async fn create(req: ReqCreate) -> ApiResult<()> { @@ -29,29 +26,29 @@ pub async fn create(req: ReqCreate) -> ApiResult<()> { .count(db::conn()) .await .map_err(|e| { - tracing::error!(error = ?e, "error find account"); + tracing::error!(err = ?e, "find account"); Code::ErrSystem(None) })?; if count > 0 { return Err(Code::ErrPerm(Some("该用户名已被使用".to_string()))); } - let salt = helper::nonce(16); - let pass = format!("{}{}", req.password, salt); + let passwd = bcrypt::hash(req.password, bcrypt::DEFAULT_COST).map_err(|e| { + tracing::error!(err = ?e, "hash password"); + Code::ErrSystem(None) + })?; let now = xtime::now(None).unix_timestamp(); let model = account::ActiveModel { username: Set(req.username), - password: Set(hash::md5(pass.as_bytes())), - salt: Set(salt), + password: Set(passwd), role: Set(1), - realname: Set(req.realname), created_at: Set(now), updated_at: Set(now), ..Default::default() }; if let Err(e) = Account::insert(model).exec(db::conn()).await { - tracing::error!(error = ?e, "error insert account"); + tracing::error!(err = ?e, "insert account"); return Err(Code::ErrSystem(None)); } @@ -62,7 +59,6 @@ pub async fn create(req: ReqCreate) -> ApiResult<()> { pub struct RespInfo { pub id: u64, pub username: String, - pub realname: String, pub login_at: i64, pub login_at_str: String, pub created_at: i64, @@ -74,7 +70,7 @@ pub async fn info(account_id: u64) -> ApiResult { .one(db::conn()) .await .map_err(|e| { - tracing::error!(error = ?e, "Error Account::find_by_id"); + tracing::error!(err = ?e, "Account::find_by_id"); Code::ErrSystem(None) })? .ok_or(Code::ErrEmpty(Some("账号不存在".to_string())))?; @@ -82,7 +78,6 @@ pub async fn info(account_id: u64) -> ApiResult { let resp = RespInfo { id: model.id, username: model.username, - realname: model.realname, login_at: model.login_at, login_at_str: xtime::to_string(xtime::DATE_TIME, model.login_at, None).unwrap_or_default(), created_at: model.created_at, @@ -119,7 +114,7 @@ pub async fn list(query: &MultiMap) -> ApiResult { .one(db::conn()) .await .map_err(|e| { - tracing::error!(error = ?e, "error count account"); + tracing::error!(err = ?e, "count account"); Code::ErrSystem(None) })? .unwrap_or_default(); @@ -132,7 +127,7 @@ pub async fn list(query: &MultiMap) -> ApiResult { .all(db::conn()) .await .map_err(|e| { - tracing::error!(error = ?e, "error find account"); + tracing::error!(err = ?e, "find account"); Code::ErrSystem(None) })?; let mut resp = RespList { @@ -143,7 +138,6 @@ pub async fn list(query: &MultiMap) -> ApiResult { let info = RespInfo { id: model.id, username: model.username, - realname: model.realname, login_at: model.login_at, login_at_str: xtime::to_string(xtime::DATE_TIME, model.login_at, None) .unwrap_or_default(), diff --git a/src/app/service/auth.rs b/src/app/service/auth.rs index af79a3d..d133636 100644 --- a/src/app/service/auth.rs +++ b/src/app/service/auth.rs @@ -32,14 +32,17 @@ pub async fn login(req: ReqLogin) -> ApiResult { .one(db::conn()) .await .map_err(|e| { - tracing::error!(error = ?e, "error find account"); + tracing::error!(err = ?e, "find account"); Code::ErrSystem(None) })? - .ok_or(Code::ErrAuth(Some("账号不存在".to_string())))?; + .ok_or(Code::ErrAuth(Some("账号或密码错误".to_string())))?; - let pass = format!("{}{}", req.password, model.salt); - if hash::md5(pass.as_bytes()) != model.password { - return Err(Code::ErrAuth(Some("密码错误".to_string()))); + let valid = bcrypt::verify(req.password, &model.password).map_err(|e| { + tracing::error!(err = ?e, "verify password"); + Code::ErrSystem(None) + })?; + if !valid { + return Err(Code::ErrAuth(Some("账号或密码错误".to_string()))); } let now = xtime::now(None).unix_timestamp(); @@ -48,7 +51,7 @@ pub async fn login(req: ReqLogin) -> ApiResult { let auth_token = Identity::new(model.id, model.role, login_token.clone()) .to_auth_token() .map_err(|e| { - tracing::error!(error = ?e, "error identity encrypt"); + tracing::error!(err = ?e, "identity encrypt"); Code::ErrSystem(None) })?; let update_model = account::ActiveModel { @@ -63,12 +66,12 @@ pub async fn login(req: ReqLogin) -> ApiResult { .exec(db::conn()) .await; if let Err(e) = ret_update { - tracing::error!(error = ?e, "error update account"); + tracing::error!(err = ?e, "update account"); return Err(Code::ErrSystem(None)); } let resp = RespLogin { - name: model.realname, + name: model.username, role: model.role, auth_token, }; @@ -88,7 +91,7 @@ pub async fn logout(identity: &Identity) -> ApiResult<()> { .await; if let Err(e) = ret { - tracing::error!(error = ?e, "error update account"); + tracing::error!(err = ?e, "update account"); return Err(Code::ErrSystem(None)); } diff --git a/src/app/service/project.rs b/src/app/service/project.rs index ddc6b4e..1014a9a 100644 --- a/src/app/service/project.rs +++ b/src/app/service/project.rs @@ -30,7 +30,7 @@ pub async fn create(id: &Identity, req: ReqCreate) -> ApiResult<()> { .count(db::conn()) .await .map_err(|e| { - tracing::error!(error = ?e, "error find project"); + tracing::error!(err = ?e, "find project"); Code::ErrSystem(None) })?; if count > 0 { @@ -48,7 +48,7 @@ pub async fn create(id: &Identity, req: ReqCreate) -> ApiResult<()> { ..Default::default() }; if let Err(e) = Project::insert(model).exec(db::conn()).await { - tracing::error!(error = ?e, "error insert project"); + tracing::error!(err = ?e, "insert project"); return Err(Code::ErrSystem(None)); } @@ -104,7 +104,7 @@ pub async fn list(id: &Identity, query: &MultiMap) -> ApiResult< .one(db::conn()) .await .map_err(|e| { - tracing::error!(error = ?e, "error count project"); + tracing::error!(err = ?e, "count project"); Code::ErrSystem(None) })? .unwrap_or_default(); @@ -117,7 +117,7 @@ pub async fn list(id: &Identity, query: &MultiMap) -> ApiResult< .all(db::conn()) .await .map_err(|e| { - tracing::error!(error = ?e, "error find project"); + tracing::error!(err = ?e, "find project"); Code::ErrSystem(None) })?; let mut resp = RespList { @@ -161,7 +161,7 @@ pub async fn detail(id: &Identity, project_id: u64) -> ApiResult { .one(db::conn()) .await .map_err(|e| { - tracing::error!(error = ?e, "error find project"); + tracing::error!(err = ?e, "find project"); Code::ErrSystem(None) })? .ok_or(Code::ErrEmpty(Some("项目不存在".to_string())))?; @@ -181,7 +181,7 @@ pub async fn detail(id: &Identity, project_id: u64) -> ApiResult { if let Some(v) = model_account { resp.account = Some(ProjAccount { id: v.id, - name: v.realname, + name: v.username, }) } diff --git a/src/shared/middleware/log.rs b/src/shared/middleware/log.rs index 7728ded..43cdb45 100644 --- a/src/shared/middleware/log.rs +++ b/src/shared/middleware/log.rs @@ -85,7 +85,7 @@ async fn drain_body(req: &mut Request) -> (Option, Option) { let bytes = match body.collect().await { Ok(v) => v.to_bytes(), Err(e) => { - tracing::error!(error = ?e, "Error body.collect"); + tracing::error!(err = ?e, "body.collect"); return (None, Some(Code::ErrSystem(None))); } }; diff --git a/src/shared/util/identity.rs b/src/shared/util/identity.rs index ea2613d..29e2253 100644 --- a/src/shared/util/identity.rs +++ b/src/shared/util/identity.rs @@ -7,6 +7,10 @@ use std::fmt::Display; use crate::config; use crate::shared::crypto::aes::CBC; +use super::xtime; + +pub const EXPIRE_SECONDS: i64 = 86400; + pub enum Role { Super, Normal, @@ -17,6 +21,7 @@ pub struct Identity { i: u64, r: i8, t: String, + x: i64, } impl Identity { @@ -25,6 +30,7 @@ impl Identity { i: id, r: role, t: token, + x: xtime::now(None).unix_timestamp() + EXPIRE_SECONDS, } } @@ -33,6 +39,7 @@ impl Identity { i: 0, r: 0, t: String::from(""), + x: 0, } } @@ -42,14 +49,14 @@ impl Identity { } let cipher = match BASE64_STANDARD.decode(token) { Err(e) => { - tracing::error!(error = ?e, "error invalid auth_token"); + tracing::error!(err = ?e, "invalid auth_token"); return Identity::empty(); } Ok(v) => v, }; let secret = match config::global().get_string("app.secret") { Err(e) => { - tracing::error!(error = ?e, "error missing config(app.secret)"); + tracing::error!(err = ?e, "missing config(app.secret)"); return Identity::empty(); } Ok(v) => v, @@ -57,7 +64,7 @@ impl Identity { let key = secret.as_bytes(); let plain = match CBC(key, &key[..16]).decrypt(&cipher) { Err(e) => { - tracing::error!(error = ?e, "error invalid auth_token"); + tracing::error!(err = ?e, "invalid auth_token"); return Identity::empty(); } Ok(v) => v, @@ -65,7 +72,7 @@ impl Identity { match serde_json::from_slice::(&plain) { Err(e) => { - tracing::error!(error = ?e, "error invalid auth_token"); + tracing::error!(err = ?e, "invalid auth_token"); Identity::empty() } Ok(identity) => identity, @@ -90,6 +97,10 @@ impl Identity { self.t == token } + pub fn is_expired(&self) -> bool { + self.x > xtime::now(None).unix_timestamp() + } + pub fn is_role(&self, role: Role) -> bool { match role { Role::Normal => self.r == 1, @@ -114,6 +125,7 @@ impl Default for Identity { i: 0, r: 0, t: String::from(""), + x: 0, } } } diff --git a/src/shared/util/mutex.rs b/src/shared/util/mutex.rs index 438ed00..e7d4a54 100644 --- a/src/shared/util/mutex.rs +++ b/src/shared/util/mutex.rs @@ -110,7 +110,7 @@ impl Drop for RedisLock { let mut conn = match cache::redis_pool().get() { Ok(v) => v, Err(e) => { - tracing::error!(error = ?e, "[mutex] redis get connection error"); + tracing::error!(err = ?e, "[mutex] redis get connection error"); return; } }; @@ -118,7 +118,7 @@ impl Drop for RedisLock { let script = redis::Script::new(SCRIPT); let ret: redis::RedisResult<()> = script.key(&self.key).arg(&self.token).invoke(&mut conn); if let Err(e) = ret { - tracing::error!(error = ?e, "[mutex] redis del key({}) error", self.key); + tracing::error!(err = ?e, "[mutex] redis del key({}) error", self.key); } } }