From 769f5a3aff6b7689ebf88ba43a474b47dca4a47d Mon Sep 17 00:00:00 2001 From: petru Date: Mon, 5 Feb 2024 17:58:30 +0200 Subject: [PATCH 01/24] 30-access-policies app domain --- Cargo.lock | 138 +++++++++++++++++++++--------------- access_control.conf.dist | 8 +-- src/middleware/client.rs | 8 +++ src/middleware/trydirect.rs | 2 +- src/startup.rs | 1 + 5 files changed, 96 insertions(+), 61 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f844c9c0..1dc15f9e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,7 +5,7 @@ version = 3 [[package]] name = "actix-casbin-auth" version = "0.4.4" -source = "git+https://github.com/smart--petea/actix-casbin-auth.git?branch=dirty-master#795c1209e4dea6078a787ccf7a882bd5d1148be7" +source = "git+https://github.com/smart--petea/actix-casbin-auth.git?branch=dirty-master#5b76cc4e0df68ccee02c563b947a788ab1cb5193" dependencies = [ "actix-service", "actix-web", @@ -16,11 +16,11 @@ dependencies = [ [[package]] name = "actix-codec" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "617a8268e3537fe1d8c9ead925fca49ef6400927ee7bc26750e90ecee14ce4b8" +checksum = "5f7b0a21988c1bf877cf4759ef5ddaac04c1c9fe808c9142ecb78ba97d97a28a" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.2", "bytes", "futures-core", "futures-sink", @@ -48,9 +48,9 @@ dependencies = [ [[package]] name = "actix-http" -version = "3.5.1" +version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "129d4c88e98860e1758c5de288d1632b07970a16d59bdf7b8d66053d582bb71f" +checksum = "d223b13fd481fc0d1f83bb12659ae774d9e3601814c68a0bc539731698cca743" dependencies = [ "actix-codec", "actix-rt", @@ -158,9 +158,9 @@ dependencies = [ [[package]] name = "actix-web" -version = "4.4.1" +version = "4.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e43428f3bf11dee6d166b00ec2df4e3aa8cc1606aaa0b7433c146852e2f4e03b" +checksum = "43a6556ddebb638c2358714d853257ed226ece6023ef9364f23f0c70737ea984" dependencies = [ "actix-codec", "actix-http", @@ -192,7 +192,7 @@ dependencies = [ "serde_urlencoded", "smallvec", "socket2 0.5.5", - "time 0.3.31", + "time 0.3.34", "url", ] @@ -372,9 +372,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +checksum = "2faccea4cc4ab4a667ce676a30e8ec13922a692c99bb8f5b11f1502c72e04220" [[package]] name = "anstyle-parse" @@ -517,7 +517,7 @@ dependencies = [ "futures-lite 2.2.0", "parking", "polling 3.3.2", - "rustix 0.38.30", + "rustix 0.38.31", "slab", "tracing", "windows-sys 0.52.0", @@ -753,9 +753,9 @@ dependencies = [ [[package]] name = "casbin" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fd06051bc34aa7ee753647dbd36506fa9f84026993d9871e65e0ee71ac3632" +checksum = "b71063d3ee2f5ecc89229ccade0f3f8fb413b5e3978124a38b611216f91dd7c9" dependencies = [ "async-trait", "fixedbitset", @@ -930,7 +930,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" dependencies = [ "percent-encoding", - "time 0.3.31", + "time 0.3.34", "version_check", ] @@ -1265,7 +1265,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e366950e7785fe0e404901a2b4e5c09ebd6656767f0c2167e34c5068ce0cc2d" dependencies = [ "derive_builder 0.13.0", - "indexmap 2.2.1", + "indexmap 2.2.2", "serde", "serde_yaml", ] @@ -1651,7 +1651,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 2.2.1", + "indexmap 2.2.2", "slab", "tokio", "tokio-util", @@ -1828,9 +1828,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.59" +version = "0.1.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -1878,9 +1878,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.1" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "433de089bd45971eecf4668ee0ee8f4cec17db4f8bd8f7bc3197a6ce37aa7d9b" +checksum = "824b2ae422412366ba479e8111fd301f7b5faece8149317bb81925979a53f520" dependencies = [ "equivalent", "hashbrown 0.14.3", @@ -1940,9 +1940,9 @@ dependencies = [ [[package]] name = "itertools" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" dependencies = [ "either", ] @@ -2019,9 +2019,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.152" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "libredox" @@ -2139,9 +2139,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" dependencies = [ "adler", ] @@ -2202,6 +2202,12 @@ dependencies = [ "winapi", ] +[[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.17" @@ -2387,9 +2393,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.6" +version = "2.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f200d8d83c44a45b21764d1916299752ca035d15ecd46faca3e9a2a2bf6ad06" +checksum = "219c0dcc30b6a27553f9cc242972b67f75b60eb0db71f0b5462f38b058c41546" dependencies = [ "memchr", "thiserror", @@ -2398,9 +2404,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.6" +version = "2.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcd6ab1236bbdb3a49027e920e693192ebfe8913f6d60e294de57463a493cfde" +checksum = "22e1288dbd7786462961e69bfd4df7848c1e37e8b74303dbdab82c3a9cdd2809" dependencies = [ "pest", "pest_generator", @@ -2408,9 +2414,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.6" +version = "2.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a31940305ffc96863a735bef7c7994a00b325a7138fdbc5bda0f1a0476d3275" +checksum = "1381c29a877c6d34b8c176e734f35d7f7f5b3adaefe940cb4d1bb7af94678e2e" dependencies = [ "pest", "pest_meta", @@ -2421,9 +2427,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.7.6" +version = "2.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7ff62f5259e53b78d1af898941cdcdccfae7385cf7d793a6e55de5d05bb4b7d" +checksum = "d0934d6907f148c22a3acbda520c7eed243ad7487a30f51f6ce52b58b7077a8a" dependencies = [ "once_cell", "pest", @@ -2437,7 +2443,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap 2.2.1", + "indexmap 2.2.2", ] [[package]] @@ -2526,7 +2532,7 @@ dependencies = [ "cfg-if", "concurrent-queue", "pin-project-lite", - "rustix 0.38.30", + "rustix 0.38.31", "tracing", "windows-sys 0.52.0", ] @@ -2762,9 +2768,9 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "reqwest" -version = "0.11.23" +version = "0.11.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" +checksum = "c6920094eb85afde5e4a138be3f2de8bbdf28000f0029e72c45025a56b042251" dependencies = [ "base64 0.21.7", "bytes", @@ -2784,9 +2790,11 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", + "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", + "sync_wrapper", "system-configuration", "tokio", "tokio-native-tls", @@ -2806,9 +2814,9 @@ checksum = "4389f1d5789befaf6029ebd9f7dac4af7f7e3d61b69d4f30e2ac02b57e7712b0" [[package]] name = "rhai" -version = "1.16.3" +version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3625f343d89990133d013e39c46e350915178cf94f1bec9f49b0cbef98a3e3c" +checksum = "f6273372244d04a8a4b0bec080ea1e710403e88c5d9d83f9808b2bfa64f0982a" dependencies = [ "ahash 0.8.7", "bitflags 2.4.2", @@ -2819,13 +2827,14 @@ dependencies = [ "serde", "smallvec", "smartstring", + "thin-vec", ] [[package]] name = "rhai_codegen" -version = "1.6.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "853977598f084a492323fe2f7896b4100a86284ee8473612de60021ea341310f" +checksum = "9db7f8dc4c9d48183a17ce550574c42995252b82d267eaca3fcd1b979159856c" dependencies = [ "proc-macro2", "quote", @@ -2923,9 +2932,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.30" +version = "0.38.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" +checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" dependencies = [ "bitflags 2.4.2", "errno", @@ -3187,7 +3196,7 @@ version = "0.9.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adf8a49373e98a4c5f0ceb5d05aa7c648d75f63774981ed95b7c7443bbd50c6e" dependencies = [ - "indexmap 2.2.1", + "indexmap 2.2.2", "itoa", "ryu", "serde", @@ -3320,7 +3329,7 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce81b7bd7c4493975347ef60d8c7e8b742d4694f4c49f93e0a12ea263938176c" dependencies = [ - "itertools 0.12.0", + "itertools 0.12.1", "nom", "unicode_categories", ] @@ -3454,7 +3463,7 @@ dependencies = [ "futures-util", "glob", "hmac", - "indexmap 2.2.1", + "indexmap 2.2.2", "lapin", "rand 0.8.5", "regex", @@ -3531,6 +3540,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + [[package]] name = "system-configuration" version = "0.5.1" @@ -3579,10 +3594,19 @@ dependencies = [ "cfg-if", "fastrand 2.0.1", "redox_syscall 0.4.1", - "rustix 0.38.30", + "rustix 0.38.31", "windows-sys 0.52.0", ] +[[package]] +name = "thin-vec" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a38c90d48152c236a3ab59271da4f4ae63d678c5d7ad6b7714d7cb9760be5e4b" +dependencies = [ + "serde", +] + [[package]] name = "thiserror" version = "1.0.56" @@ -3626,12 +3650,13 @@ dependencies = [ [[package]] name = "time" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" +checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" dependencies = [ "deranged", "itoa", + "num-conv", "powerfmt", "serde", "time-core", @@ -3646,10 +3671,11 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" +checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" dependencies = [ + "num-conv", "time-core", ] @@ -3679,9 +3705,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.35.1" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" dependencies = [ "backtrace", "bytes", @@ -3826,7 +3852,7 @@ dependencies = [ "log", "serde", "serde_json", - "time 0.3.31", + "time 0.3.34", "tracing", "tracing-core", "tracing-log 0.1.4", diff --git a/access_control.conf.dist b/access_control.conf.dist index 459a15fc..5d047154 100644 --- a/access_control.conf.dist +++ b/access_control.conf.dist @@ -1,14 +1,14 @@ [request_definition] -r = sub, obj, act +r = sub, dom, obj, act [policy_definition] -p = sub, obj, act +p = sub, dom, obj, act [role_definition] -g = _, _ +g = _, _, _ [policy_effect] e = some(where (p.eft == allow)) [matchers] -m = g(r.sub, p.sub) && r.obj == p.obj && regexMatch(r.act, p.act) +m = g(r.sub, p.sub, r.dom) && r.dom == p.dom && r.obj == p.obj && regexMatch(r.act, p.act) diff --git a/src/middleware/client.rs b/src/middleware/client.rs index a6915d55..def95b06 100644 --- a/src/middleware/client.rs +++ b/src/middleware/client.rs @@ -96,6 +96,14 @@ where None => {} } + let accesscontrol_vals = actix_casbin_auth::CasbinVals { + subject: client_id.to_string(), + domain: Some(String::from("app")), + }; + if req.extensions_mut().insert(accesscontrol_vals).is_some() { + return Err("sth wrong with access control".to_string()); + } + Ok(req) } .then(|req| async move { diff --git a/src/middleware/trydirect.rs b/src/middleware/trydirect.rs index 1c61049f..c0703799 100644 --- a/src/middleware/trydirect.rs +++ b/src/middleware/trydirect.rs @@ -22,7 +22,7 @@ pub async fn bearer_guard( req: ServiceRequest, credentials: BearerAuth) -> Resu let accesscontrol_vals = actix_casbin_auth::CasbinVals { subject: String::from("alice"), - domain: None, + domain: Some(String::from("human")), }; if req.extensions_mut().insert(accesscontrol_vals).is_some() { return Err((JsonResponse::::build().unauthorized("sth wrong with access control"), req)); diff --git a/src/startup.rs b/src/startup.rs index 35481927..1c43fc77 100644 --- a/src/startup.rs +++ b/src/startup.rs @@ -42,6 +42,7 @@ pub async fn run( ) .service( web::scope("/test") + .wrap(access_control_manager.clone()) .wrap(middleware::client::Guard::new()) .wrap(Cors::permissive()) .service(crate::routes::test::deploy::handler), From 4d39ea5300f704044156bd3d277d0d6cff7710c3 Mon Sep 17 00:00:00 2001 From: petru Date: Sat, 10 Feb 2024 20:00:14 +0200 Subject: [PATCH 02/24] 30-access-policies sqlx-adapter. new version --- Cargo.lock | 343 +++++++++++++++++++++++++++++++++++++++++++---------- Cargo.toml | 3 +- 2 files changed, 281 insertions(+), 65 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1dc15f9e..269e5798 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -372,9 +372,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2faccea4cc4ab4a667ce676a30e8ec13922a692c99bb8f5b11f1502c72e04220" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" [[package]] name = "anstyle-parse" @@ -433,13 +433,13 @@ dependencies = [ [[package]] name = "async-channel" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ca33f4bc4ed1babef42cad36cc1f51fa88be00420404e5b1e80ab1b18f7678c" +checksum = "f28243a43d821d11341ab73c80bed182dc015c514b951616cf79bd4af39af0c3" dependencies = [ "concurrent-queue", - "event-listener 4.0.3", - "event-listener-strategy", + "event-listener 5.0.0", + "event-listener-strategy 0.5.0", "futures-core", "pin-project-lite", ] @@ -464,7 +464,7 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" dependencies = [ - "async-channel 2.1.1", + "async-channel 2.2.0", "async-executor", "async-io 2.3.1", "async-lock 3.3.0", @@ -516,7 +516,7 @@ dependencies = [ "futures-io", "futures-lite 2.2.0", "parking", - "polling 3.3.2", + "polling 3.4.0", "rustix 0.38.31", "slab", "tracing", @@ -539,7 +539,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" dependencies = [ "event-listener 4.0.3", - "event-listener-strategy", + "event-listener-strategy 0.4.0", "pin-project-lite", ] @@ -581,12 +581,31 @@ dependencies = [ "num-traits", ] +[[package]] +name = "atoi" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" +dependencies = [ + "num-traits", +] + [[package]] name = "atomic-waker" version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" +[[package]] +name = "atomic-write-file" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edcdbedc2236483ab103a53415653d6b4442ea6141baf1ffa85df29635e88436" +dependencies = [ + "nix", + "rand 0.8.5", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -656,7 +675,7 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118" dependencies = [ - "async-channel 2.1.1", + "async-channel 2.2.0", "async-lock 3.3.0", "async-task", "fastrand 2.0.1", @@ -731,9 +750,9 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ceed8ef69d8518a5dda55c07425450b58a4e1946f4951eab6d7191ee86c2443d" +checksum = "694c8807f2ae16faecc43dc17d74b3eb042482789fd0eb64b39a2e04e087053f" dependencies = [ "serde", ] @@ -825,9 +844,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.18" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" +checksum = "80c21025abd42669a92efc996ef13cfb2c5c627858421ea58d5c3b331a6c134f" dependencies = [ "clap_builder", "clap_derive", @@ -835,21 +854,21 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.18" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" +checksum = "458bf1f341769dfcf849846f65dffdf9146daa56bcd2a47cb4e1de9915567c99" dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim", + "strsim 0.11.0", ] [[package]] name = "clap_derive" -version = "4.4.7" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" dependencies = [ "heck", "proc-macro2", @@ -859,9 +878,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] name = "colorchoice" @@ -1049,7 +1068,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim", + "strsim 0.10.0", "syn 1.0.109", ] @@ -1284,9 +1303,9 @@ checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" [[package]] name = "either" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" dependencies = [ "serde", ] @@ -1325,6 +1344,17 @@ dependencies = [ "version_check", ] +[[package]] +name = "etcetera" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +dependencies = [ + "cfg-if", + "home", + "windows-sys 0.48.0", +] + [[package]] name = "event-listener" version = "2.5.3" @@ -1342,6 +1372,17 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "event-listener" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b72557800024fabbaa2449dd4bf24e37b93702d457a4d4f2b0dd1f0f039f20c1" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + [[package]] name = "event-listener-strategy" version = "0.4.0" @@ -1352,6 +1393,16 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "event-listener-strategy" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "feedafcaa9b749175d5ac357452a9d41ea2911da598fde46ce1fe02c37751291" +dependencies = [ + "event-listener 5.0.0", + "pin-project-lite", +] + [[package]] name = "executor-trait" version = "2.1.0" @@ -1502,6 +1553,17 @@ dependencies = [ "parking_lot 0.11.2", ] +[[package]] +name = "futures-intrusive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot 0.12.1", +] + [[package]] name = "futures-io" version = "0.3.30" @@ -1706,9 +1768,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d3d0e0f38255e7fa3cf31335b3a56f05febd18025f4db5ef7a0cfb4f8da651f" +checksum = "d0c62115964e08cb8039170eb33c1d0e2388a256930279edca206fff675f82c3" [[package]] name = "hex" @@ -1734,6 +1796,15 @@ dependencies = [ "digest", ] +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "http" version = "0.2.11" @@ -1955,18 +2026,18 @@ checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "jobserver" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.67" +version = "0.3.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" +checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" dependencies = [ "wasm-bindgen", ] @@ -2182,6 +2253,17 @@ dependencies = [ "tempfile", ] +[[package]] +name = "nix" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" +dependencies = [ + "bitflags 2.4.2", + "cfg-if", + "libc", +] + [[package]] name = "nom" version = "7.1.3" @@ -2210,9 +2292,9 @@ checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" dependencies = [ "autocfg", ] @@ -2525,9 +2607,9 @@ dependencies = [ [[package]] name = "polling" -version = "3.3.2" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "545c980a3880efd47b2e262f6a4bb6daad6555cf3367aa9c4e52895f69537a41" +checksum = "30054e72317ab98eddd8561db0f6524df3367636884b7b21b703e4b280a84a14" dependencies = [ "cfg-if", "concurrent-queue", @@ -3176,7 +3258,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "strsim", + "strsim 0.10.0", "syn 1.0.109", ] @@ -3340,19 +3422,31 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8de3b03a925878ed54a954f621e64bf55a3c1bd29652d0d1a17830405350188" dependencies = [ - "sqlx-core", - "sqlx-macros", + "sqlx-core 0.6.3", + "sqlx-macros 0.6.3", +] + +[[package]] +name = "sqlx" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dba03c279da73694ef99763320dea58b51095dfe87d001b1d4b5fe78ba8763cf" +dependencies = [ + "sqlx-core 0.7.3", + "sqlx-macros 0.7.3", + "sqlx-postgres", ] [[package]] name = "sqlx-adapter" -version = "0.4.2" -source = "git+https://github.com/smart--petea/sqlx-adapter.git?branch=dirty-master#5f7cabbde494098a1b460f26c4b74fcbcf2d5857" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e39a25e18b8f9cd4f61b1653be67260d28dcd31b0bd8d3a08ed3ecbe2afa3b84" dependencies = [ "async-trait", "casbin", "dotenv", - "sqlx", + "sqlx 0.7.3", ] [[package]] @@ -3362,7 +3456,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa8241483a83a3f33aa5fff7e7d9def398ff9990b2752b6c6112b83c6d246029" dependencies = [ "ahash 0.7.7", - "atoi", + "atoi 1.0.0", "base64 0.13.1", "bitflags 1.3.2", "byteorder", @@ -3376,7 +3470,7 @@ dependencies = [ "event-listener 2.5.3", "futures-channel", "futures-core", - "futures-intrusive", + "futures-intrusive 0.4.2", "futures-util", "hashlink", "hex", @@ -3410,6 +3504,47 @@ dependencies = [ "whoami", ] +[[package]] +name = "sqlx-core" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d84b0a3c3739e220d94b3239fd69fb1f74bc36e16643423bd99de3b43c21bfbd" +dependencies = [ + "ahash 0.8.7", + "atoi 2.0.0", + "byteorder", + "bytes", + "crc", + "crossbeam-queue", + "dotenvy", + "either", + "event-listener 2.5.3", + "futures-channel", + "futures-core", + "futures-intrusive 0.5.0", + "futures-io", + "futures-util", + "hashlink", + "hex", + "indexmap 2.2.2", + "log", + "memchr", + "native-tls", + "once_cell", + "paste", + "percent-encoding", + "serde", + "serde_json", + "sha2", + "smallvec", + "sqlformat", + "thiserror", + "tokio", + "tokio-stream", + "tracing", + "url", +] + [[package]] name = "sqlx-macros" version = "0.6.3" @@ -3426,12 +3561,89 @@ dependencies = [ "serde", "serde_json", "sha2", - "sqlx-core", + "sqlx-core 0.6.3", "sqlx-rt", "syn 1.0.109", "url", ] +[[package]] +name = "sqlx-macros" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89961c00dc4d7dffb7aee214964b065072bff69e36ddb9e2c107541f75e4f2a5" +dependencies = [ + "proc-macro2", + "quote", + "sqlx-core 0.7.3", + "sqlx-macros-core", + "syn 1.0.109", +] + +[[package]] +name = "sqlx-macros-core" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0bd4519486723648186a08785143599760f7cc81c52334a55d6a83ea1e20841" +dependencies = [ + "atomic-write-file", + "dotenvy", + "either", + "heck", + "hex", + "once_cell", + "proc-macro2", + "quote", + "serde", + "serde_json", + "sha2", + "sqlx-core 0.7.3", + "sqlx-postgres", + "syn 1.0.109", + "tempfile", + "tokio", + "url", +] + +[[package]] +name = "sqlx-postgres" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6ac0ac3b7ccd10cc96c7ab29791a7dd236bd94021f31eec7ba3d46a74aa1c24" +dependencies = [ + "atoi 2.0.0", + "base64 0.21.7", + "bitflags 2.4.2", + "byteorder", + "crc", + "dotenvy", + "etcetera", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "hex", + "hkdf", + "hmac", + "home", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "rand 0.8.5", + "serde", + "serde_json", + "sha1", + "sha2", + "smallvec", + "sqlx-core 0.7.3", + "stringprep", + "thiserror", + "tracing", + "whoami", +] + [[package]] name = "sqlx-rt" version = "0.6.3" @@ -3475,7 +3687,7 @@ dependencies = [ "serde_valid", "serde_yaml", "sha2", - "sqlx", + "sqlx 0.6.3", "sqlx-adapter", "thiserror", "tokio", @@ -3512,6 +3724,12 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strsim" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" + [[package]] name = "subtle" version = "2.5.0" @@ -3587,13 +3805,12 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.9.0" +version = "3.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" +checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67" dependencies = [ "cfg-if", "fastrand 2.0.1", - "redox_syscall 0.4.1", "rustix 0.38.31", "windows-sys 0.52.0", ] @@ -3965,9 +4182,9 @@ dependencies = [ [[package]] name = "unicode-segmentation" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "unicode_categories" @@ -4084,9 +4301,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.90" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" +checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -4094,9 +4311,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.90" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" +checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" dependencies = [ "bumpalo", "log", @@ -4109,9 +4326,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.40" +version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bde2032aeb86bdfaecc8b261eef3cba735cc426c1f3a3416d1e0791be95fc461" +checksum = "877b9c3f61ceea0e56331985743b13f3d25c406a7098d45180fb5f09bc19ed97" dependencies = [ "cfg-if", "js-sys", @@ -4121,9 +4338,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.90" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" +checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4131,9 +4348,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.90" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" +checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" dependencies = [ "proc-macro2", "quote", @@ -4144,15 +4361,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.90" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" +checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" [[package]] name = "web-sys" -version = "0.3.67" +version = "0.3.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" +checksum = "96565907687f7aceb35bc5fc03770a8a0471d82e479f25832f54a0e3f4b28446" dependencies = [ "js-sys", "wasm-bindgen", diff --git a/Cargo.toml b/Cargo.toml index 89420989..20a127c1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,8 +44,7 @@ tokio-stream = "0.1.14" actix-http = "3.4.0" hmac = "0.12.1" sha2 = "0.10.8" -#sqlx-adapter = { version = "0.4.2", default-features = false, features = ["postgres", "runtime-tokio-native-tls"]} -sqlx-adapter = { git="https://github.com/smart--petea/sqlx-adapter.git", branch="dirty-master", default-features = false, features = ["postgres"]} +sqlx-adapter = { version = "1.0.0", default-features = false, features = ["postgres", "runtime-tokio-native-tls"]} # dctypes derive_builder = "0.12.0" From c53bcb79f77e353633730294dfb1c4b0efca9960 Mon Sep 17 00:00:00 2001 From: petru Date: Wed, 14 Feb 2024 18:18:35 +0200 Subject: [PATCH 03/24] 30-access-policies --- access_control.conf.dist | 8 ++++---- src/forms/mod.rs | 1 + src/forms/user.rs | 4 +++- src/middleware/client.rs | 2 +- src/middleware/trydirect.rs | 16 +++++++++------- src/startup.rs | 9 ++++++++- 6 files changed, 26 insertions(+), 14 deletions(-) diff --git a/access_control.conf.dist b/access_control.conf.dist index 5d047154..f164af1a 100644 --- a/access_control.conf.dist +++ b/access_control.conf.dist @@ -1,14 +1,14 @@ [request_definition] -r = sub, dom, obj, act +r = sub, obj, act [policy_definition] -p = sub, dom, obj, act +p = sub, obj, act [role_definition] -g = _, _, _ +g = _, _ [policy_effect] e = some(where (p.eft == allow)) [matchers] -m = g(r.sub, p.sub, r.dom) && r.dom == p.dom && r.obj == p.obj && regexMatch(r.act, p.act) +m = g(r.sub, p.sub) && keyMatch2(r.obj, p.obj) && r.act == p.act diff --git a/src/forms/mod.rs b/src/forms/mod.rs index 9647ea6e..273c2a06 100644 --- a/src/forms/mod.rs +++ b/src/forms/mod.rs @@ -3,3 +3,4 @@ pub mod stack; pub mod user; pub use rating::*; +pub use user::UserForm; diff --git a/src/forms/user.rs b/src/forms/user.rs index 8ff0b4ce..0fd00246 100644 --- a/src/forms/user.rs +++ b/src/forms/user.rs @@ -10,6 +10,8 @@ pub struct UserForm { pub user: User, } +//todo deref for UserForm. userForm.id, userForm.first_name + #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Validate)] #[serde(rename_all = "camelCase")] pub struct User { @@ -139,4 +141,4 @@ impl TryInto for UserForm { }) } -} \ No newline at end of file +} diff --git a/src/middleware/client.rs b/src/middleware/client.rs index def95b06..7345223e 100644 --- a/src/middleware/client.rs +++ b/src/middleware/client.rs @@ -98,7 +98,7 @@ where let accesscontrol_vals = actix_casbin_auth::CasbinVals { subject: client_id.to_string(), - domain: Some(String::from("app")), + domain: None, }; if req.extensions_mut().insert(accesscontrol_vals).is_some() { return Err("sth wrong with access control".to_string()); diff --git a/src/middleware/trydirect.rs b/src/middleware/trydirect.rs index c0703799..e9ce5eb8 100644 --- a/src/middleware/trydirect.rs +++ b/src/middleware/trydirect.rs @@ -1,4 +1,6 @@ -use crate::{models, configuration::Settings, forms::user::UserForm, helpers::JsonResponse}; +use crate::{configuration::Settings, helpers::JsonResponse}; +use crate::models; +use crate::forms; use actix_web::{web, dev::ServiceRequest, Error, HttpMessage}; use actix_web_httpauth::extractors::bearer::BearerAuth; use futures::future::{FutureExt}; @@ -12,20 +14,20 @@ pub async fn bearer_guard( req: ServiceRequest, credentials: BearerAuth) -> Resu let user = match fetch_user(settings.auth_url.as_str(), token).await { Ok(user) => user, Err(err) => { - return Err((JsonResponse::::build().unauthorized(err), req)); + return Err((JsonResponse::::build().unauthorized(err), req)); //todo anonymous } }; if req.extensions_mut().insert(Arc::new(user)).is_some() { - return Err((JsonResponse::::build().unauthorized("user already logged"), req)); + return Err((JsonResponse::::build().unauthorized("user already logged"), req)); //todo 500 internal error } let accesscontrol_vals = actix_casbin_auth::CasbinVals { - subject: String::from("alice"), - domain: Some(String::from("human")), + subject: String::from("alice"), //todo username or anonymous + domain: None, }; if req.extensions_mut().insert(accesscontrol_vals).is_some() { - return Err((JsonResponse::::build().unauthorized("sth wrong with access control"), req)); + return Err((JsonResponse::::build().unauthorized("sth wrong with access control"), req)); //todo 500 internal error } Ok(req) @@ -47,7 +49,7 @@ async fn fetch_user(auth_url: &str, token: &str) -> Result } resp - .json::() + .json::() .await .map_err(|_err| "can't parse the response body".to_string())? .try_into() diff --git a/src/startup.rs b/src/startup.rs index 1c43fc77..45f14640 100644 --- a/src/startup.rs +++ b/src/startup.rs @@ -28,7 +28,14 @@ pub async fn run( let server = HttpServer::new(move || { App::new() .wrap(TracingLogger::default()) - .service(web::scope("/health_check").service(crate::routes::health_check)) + .service( + web::scope("/health_check") + .wrap(HttpAuthentication::bearer( + middleware::trydirect::bearer_guard, + )) + .wrap(Cors::permissive()) + .service(crate::routes::health_check) + ) .service( web::scope("/client") .wrap(HttpAuthentication::bearer( From ff82dbf72bbae09dfc0229f4721e3743f591b39c Mon Sep 17 00:00:00 2001 From: petru Date: Sat, 17 Feb 2024 08:03:05 +0200 Subject: [PATCH 04/24] 30-access-policies replace crate::routes::xxx with routes::xx --- src/startup.rs | 70 +++++++++++++++++++------------------------------- 1 file changed, 26 insertions(+), 44 deletions(-) diff --git a/src/startup.rs b/src/startup.rs index 45f14640..447f2dd2 100644 --- a/src/startup.rs +++ b/src/startup.rs @@ -1,5 +1,6 @@ use crate::configuration::Settings; use crate::helpers; +use crate::routes; use actix_cors::Cors; use actix_web::dev::Server; use actix_web::{ @@ -28,64 +29,45 @@ pub async fn run( let server = HttpServer::new(move || { App::new() .wrap(TracingLogger::default()) - .service( - web::scope("/health_check") - .wrap(HttpAuthentication::bearer( + /* + .wrap(middleware::client::Guard::new()) + .wrap(HttpAuthentication::bearer( middleware::trydirect::bearer_guard, - )) - .wrap(Cors::permissive()) - .service(crate::routes::health_check) + )) + */ + .wrap(access_control_manager.clone()) + .wrap(Cors::permissive()) + .service( + web::scope("/health_check").service(routes::health_check) ) .service( web::scope("/client") - .wrap(HttpAuthentication::bearer( - middleware::trydirect::bearer_guard, - )) - .wrap(Cors::permissive()) - .service(crate::routes::client::add_handler) - .service(crate::routes::client::update_handler) - .service(crate::routes::client::enable_handler) - .service(crate::routes::client::disable_handler), + .service(routes::client::add_handler) + .service(routes::client::update_handler) + .service(routes::client::enable_handler) + .service(routes::client::disable_handler), ) .service( - web::scope("/test") - .wrap(access_control_manager.clone()) - .wrap(middleware::client::Guard::new()) - .wrap(Cors::permissive()) - .service(crate::routes::test::deploy::handler), + web::scope("/test").service(routes::test::deploy::handler), ) .service( - web::scope("/pen/1") - .wrap(access_control_manager.clone()) - .wrap(HttpAuthentication::bearer( - middleware::trydirect::bearer_guard, - )) - .wrap(Cors::permissive()) - .service(crate::routes::test::casbin::handler), + web::scope("/pen/1").service(routes::test::casbin::handler), ) .service( web::scope("/rating") - .wrap(HttpAuthentication::bearer( - middleware::trydirect::bearer_guard, - )) - .wrap(Cors::permissive()) - .service(crate::routes::rating::add_handler) - .service(crate::routes::rating::get_handler) - .service(crate::routes::rating::list_handler), + .service(routes::rating::add_handler) + .service(routes::rating::get_handler) + .service(routes::rating::list_handler), ) .service( web::scope("/stack") - .wrap(HttpAuthentication::bearer( - middleware::trydirect::bearer_guard, - )) - .wrap(Cors::permissive()) - .service(crate::routes::stack::deploy::add) - .service(crate::routes::stack::compose::add) - .service(crate::routes::stack::compose::admin) - .service(crate::routes::stack::get::item) - .service(crate::routes::stack::get::list) - .service(crate::routes::stack::add::add) - .service(crate::routes::stack::update::update), + .service(routes::stack::deploy::add) + .service(routes::stack::compose::add) + .service(routes::stack::compose::admin) + .service(routes::stack::get::item) + .service(routes::stack::get::list) + .service(routes::stack::add::add) + .service(routes::stack::update::update), ) .app_data(pg_pool.clone()) .app_data(mq_manager.clone()) From 7e575c699252a2afbe35c0e7037b8d2c7248483c Mon Sep 17 00:00:00 2001 From: petru Date: Sat, 17 Feb 2024 08:12:46 +0200 Subject: [PATCH 05/24] 30-access-policies authorization manager --- .../{access_manager.rs => authorization_manager.rs} | 0 src/middleware/mod.rs | 2 +- src/startup.rs | 4 ++-- 3 files changed, 3 insertions(+), 3 deletions(-) rename src/middleware/{access_manager.rs => authorization_manager.rs} (100%) diff --git a/src/middleware/access_manager.rs b/src/middleware/authorization_manager.rs similarity index 100% rename from src/middleware/access_manager.rs rename to src/middleware/authorization_manager.rs diff --git a/src/middleware/mod.rs b/src/middleware/mod.rs index 59debf10..97bbd746 100644 --- a/src/middleware/mod.rs +++ b/src/middleware/mod.rs @@ -1,3 +1,3 @@ pub mod client; pub mod trydirect; -pub mod access_manager; +pub mod authorization_manager; diff --git a/src/startup.rs b/src/startup.rs index 447f2dd2..9df9ab20 100644 --- a/src/startup.rs +++ b/src/startup.rs @@ -24,7 +24,7 @@ pub async fn run( let mq_manager = helpers::MqManager::try_new(settings.amqp.connection_string())?; let mq_manager = web::Data::new(mq_manager); - let access_control_manager = middleware::access_manager::try_new(settings.database.connection_string()).await?; + let authorization_manager = middleware::authorization_manager::try_new(settings.database.connection_string()).await?; let server = HttpServer::new(move || { App::new() @@ -35,7 +35,7 @@ pub async fn run( middleware::trydirect::bearer_guard, )) */ - .wrap(access_control_manager.clone()) + .wrap(authorization_manager.clone()) .wrap(Cors::permissive()) .service( web::scope("/health_check").service(routes::health_check) From eae011695cb9e64d8ece1442f1c2e4c2738ca362 Mon Sep 17 00:00:00 2001 From: petru Date: Sat, 17 Feb 2024 08:25:13 +0200 Subject: [PATCH 06/24] 30-access-polices - Authorization/Authentication manager --- .../{client.rs => authentication/mod.rs} | 16 +++++----- src/middleware/authorization_manager.rs | 32 ------------------- src/middleware/mod.rs | 4 +-- src/startup.rs | 11 ++----- 4 files changed, 13 insertions(+), 50 deletions(-) rename src/middleware/{client.rs => authentication/mod.rs} (94%) delete mode 100644 src/middleware/authorization_manager.rs diff --git a/src/middleware/client.rs b/src/middleware/authentication/mod.rs similarity index 94% rename from src/middleware/client.rs rename to src/middleware/authentication/mod.rs index 7345223e..81adf906 100644 --- a/src/middleware/client.rs +++ b/src/middleware/authentication/mod.rs @@ -22,15 +22,15 @@ use actix_web::{ }; use sqlx::{Pool, Postgres}; -pub struct Guard {} +pub struct Manager {} -impl Guard { +impl Manager { pub fn new() -> Self { Self {} } } -impl Transform for Guard +impl Transform for Manager where S: Service, Error = Error> + 'static, S::Future: 'static, @@ -39,21 +39,21 @@ where type Response = ServiceResponse; type Error = Error; type InitError = (); - type Transform = GuardMiddleware; + type Transform = ManagerMiddleware; type Future = Ready>; fn new_transform(&self, service: S) -> Self::Future { - ready(Ok(GuardMiddleware { + ready(Ok(ManagerMiddleware { service: Arc::new(Mutex::new(service)), })) } } -pub struct GuardMiddleware { +pub struct ManagerMiddleware { service: Arc>, } -impl Service for GuardMiddleware +impl Service for ManagerMiddleware where S: Service, Error = Error> + 'static, S::Future: 'static, @@ -66,7 +66,7 @@ where fn poll_ready(&self, ctx: &mut Context<'_>) -> Poll> { self.service .try_lock() - .expect("GuardMiddleware was called allready") + .expect("Authentication ManagerMiddleware was called allready") .poll_ready(ctx) } diff --git a/src/middleware/authorization_manager.rs b/src/middleware/authorization_manager.rs deleted file mode 100644 index 47601146..00000000 --- a/src/middleware/authorization_manager.rs +++ /dev/null @@ -1,32 +0,0 @@ -use actix_casbin_auth::{ - CasbinService, - casbin::{ - DefaultModel, - CoreApi, - function_map::key_match2 - } -}; -use std::io::{Error, ErrorKind}; -use sqlx_adapter::SqlxAdapter; - -pub async fn try_new(db_connection_address: String) -> Result { - let m = DefaultModel::from_file("access_control.conf") - .await - .map_err(|err| Error::new(ErrorKind::Other, format!("{err:?}")))?; - let a = SqlxAdapter::new(db_connection_address, 8) - .await - .map_err(|err| Error::new(ErrorKind::Other, format!("{err:?}")))?; - - let mut casbin_service = CasbinService::new(m, a) - .await - .map_err(|err| Error::new(ErrorKind::Other, format!("{err:?}")))?; - - casbin_service - .write() - .await - .get_role_manager() - .write() - .matching_fn(Some(key_match2), None); - - Ok(casbin_service) -} diff --git a/src/middleware/mod.rs b/src/middleware/mod.rs index 97bbd746..5efc32ed 100644 --- a/src/middleware/mod.rs +++ b/src/middleware/mod.rs @@ -1,3 +1,3 @@ -pub mod client; +pub mod authentication; pub mod trydirect; -pub mod authorization_manager; +pub mod authorization; diff --git a/src/startup.rs b/src/startup.rs index 9df9ab20..83b8548b 100644 --- a/src/startup.rs +++ b/src/startup.rs @@ -24,18 +24,13 @@ pub async fn run( let mq_manager = helpers::MqManager::try_new(settings.amqp.connection_string())?; let mq_manager = web::Data::new(mq_manager); - let authorization_manager = middleware::authorization_manager::try_new(settings.database.connection_string()).await?; + let authorization = middleware::authorization::try_new(settings.database.connection_string()).await?; let server = HttpServer::new(move || { App::new() .wrap(TracingLogger::default()) - /* - .wrap(middleware::client::Guard::new()) - .wrap(HttpAuthentication::bearer( - middleware::trydirect::bearer_guard, - )) - */ - .wrap(authorization_manager.clone()) + .wrap(middleware::authentication::Manager::new()) + .wrap(authorization.clone()) .wrap(Cors::permissive()) .service( web::scope("/health_check").service(routes::health_check) From e4ad08ab5ed81d94094de3c7a24672769384b44b Mon Sep 17 00:00:00 2001 From: petru Date: Sat, 17 Feb 2024 08:43:02 +0200 Subject: [PATCH 07/24] 30-access-policies get_header --- src/middleware/authentication/mod.rs | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/middleware/authentication/mod.rs b/src/middleware/authentication/mod.rs index 81adf906..c2a1450e 100644 --- a/src/middleware/authentication/mod.rs +++ b/src/middleware/authentication/mod.rs @@ -73,8 +73,8 @@ where fn call(&self, mut req: ServiceRequest) -> Self::Future { let service = self.service.clone(); async move { - let client_id: i32 = get_header(&req, "stacker-id")?; - let header_hash: String = get_header(&req, "stacker-hash")?; + let client_id: i32 = get_header(&req, "stacker-id")?.unwrap(); //todo + let header_hash: String = get_header(&req, "stacker-hash")?.unwrap(); //todo let db_pool = req.app_data::>>().unwrap().get_ref(); let client: Client = db_fetch_client(db_pool, client_id).await?; @@ -121,25 +121,28 @@ where } } -fn get_header(req: &ServiceRequest, header_name: &'static str) -> Result +fn get_header(req: &ServiceRequest, header_name: &'static str) -> Result, String> where T: FromStr, { let header_value = req .headers() - .get(HeaderName::from_static(header_name)) - .ok_or(format!("header {header_name} not found"))?; + .get(HeaderName::from_static(header_name)); - let header_value: &str = header_value - .to_str() - .map_err(|_| format!("header {header_name} can't be converted to string"))?; + if header_value.is_none() { + return Ok(None); + } header_value + .unwrap() + .to_str() + .map_err(|_| format!("header {header_name} can't be converted to string"))? .parse::() .map_err(|_| format!("header {header_name} has wrong type")) + .map(|v| Some(v)) } -async fn db_fetch_client(db_pool: &Pool, client_id: i32) -> Result { +async fn db_fetch_client(db_pool: &Pool, client_id: i32) -> Result { //todo let query_span = tracing::info_span!("Fetching the client by ID"); sqlx::query_as!( @@ -162,7 +165,7 @@ async fn db_fetch_client(db_pool: &Pool, client_id: i32) -> Result Result { - let content_length: usize = get_header(req, CONTENT_LENGTH.as_str())?; + let content_length: usize = get_header(req, CONTENT_LENGTH.as_str())?.unwrap(); //todo let mut body = BytesMut::with_capacity(content_length); let mut payload = req.take_payload(); while let Some(chunk) = payload.next().await { From be13d2a572a0a43a07af931fb127bc46d4f58d82 Mon Sep 17 00:00:00 2001 From: petru Date: Sat, 17 Feb 2024 17:38:08 +0200 Subject: [PATCH 08/24] 30-access-policies app authorization --- src/middleware/authentication/mod.rs | 83 ++++++++++++++++++---------- src/startup.rs | 2 +- 2 files changed, 54 insertions(+), 31 deletions(-) diff --git a/src/middleware/authentication/mod.rs b/src/middleware/authentication/mod.rs index c2a1450e..4a1851e3 100644 --- a/src/middleware/authentication/mod.rs +++ b/src/middleware/authentication/mod.rs @@ -73,40 +73,25 @@ where fn call(&self, mut req: ServiceRequest) -> Self::Future { let service = self.service.clone(); async move { - let client_id: i32 = get_header(&req, "stacker-id")?.unwrap(); //todo - let header_hash: String = get_header(&req, "stacker-hash")?.unwrap(); //todo - - let db_pool = req.app_data::>>().unwrap().get_ref(); - let client: Client = db_fetch_client(db_pool, client_id).await?; - if client.secret.is_none() { - return Err("client is not active".to_string()); - } - - let client_secret = client.secret.as_ref().unwrap().as_bytes(); - let body_hash = compute_body_hash(&mut req, client_secret).await?; - if header_hash != body_hash { - return Err("hash is wrong".to_string()); - } - - match req.extensions_mut().insert(Arc::new(client)) { - Some(_) => { - tracing::error!("client middleware already called once"); - return Err("".to_string()); + let authorization = get_header::(&req, "authorization")?; + let client_id = get_header::(&req, "stacker-id")?; + if authorization.is_some() { + //try_authorize_bearer(); //todo + } else if client_id.is_some() { + try_authorize_id_hash(&mut req, client_id.unwrap()).await?; + } else { + let accesscontrol_vals = actix_casbin_auth::CasbinVals { + subject: "anonym".to_string(), + domain: None, + }; + if req.extensions_mut().insert(accesscontrol_vals).is_some() { + return Err("sth wrong with access control".to_string()); } - None => {} - } - - let accesscontrol_vals = actix_casbin_auth::CasbinVals { - subject: client_id.to_string(), - domain: None, - }; - if req.extensions_mut().insert(accesscontrol_vals).is_some() { - return Err("sth wrong with access control".to_string()); } Ok(req) } - .then(|req| async move { + .then(|req: Result| async move { match req { Ok(req) => { let service = service.lock().await; @@ -165,7 +150,7 @@ async fn db_fetch_client(db_pool: &Pool, client_id: i32) -> Result Result { - let content_length: usize = get_header(req, CONTENT_LENGTH.as_str())?.unwrap(); //todo + let content_length: usize = get_header(req, CONTENT_LENGTH.as_str())?.unwrap(); let mut body = BytesMut::with_capacity(content_length); let mut payload = req.take_payload(); while let Some(chunk) = payload.next().await { @@ -188,3 +173,41 @@ async fn compute_body_hash(req: &mut ServiceRequest, client_secret: &[u8]) -> Re Ok(format!("{:x}", mac.finalize().into_bytes())) } + +async fn try_authorize_id_hash(req: &mut ServiceRequest, client_id: i32) -> Result<(), String> { + let header_hash = get_header::(&req, "stacker-hash")?; + if header_hash.is_none() { + return Err("stacker-hash header is not set".to_string()); + } //todo + let header_hash = header_hash.unwrap(); + + let db_pool = req.app_data::>>().unwrap().get_ref(); + let client: Client = db_fetch_client(db_pool, client_id).await?; + if client.secret.is_none() { + return Err("client is not active".to_string()); + } + + let client_secret = client.secret.as_ref().unwrap().as_bytes(); + let body_hash = compute_body_hash(req, client_secret).await?; + if header_hash != body_hash { + return Err("hash is wrong".to_string()); + } + + match req.extensions_mut().insert(Arc::new(client)) { + Some(_) => { + tracing::error!("client middleware already called once"); + return Err("".to_string()); + } + None => {} + } + + let accesscontrol_vals = actix_casbin_auth::CasbinVals { + subject: client_id.to_string(), + domain: None, + }; + if req.extensions_mut().insert(accesscontrol_vals).is_some() { + return Err("sth wrong with access control".to_string()); + } + + Ok(()) +} diff --git a/src/startup.rs b/src/startup.rs index 83b8548b..279044e6 100644 --- a/src/startup.rs +++ b/src/startup.rs @@ -29,8 +29,8 @@ pub async fn run( let server = HttpServer::new(move || { App::new() .wrap(TracingLogger::default()) - .wrap(middleware::authentication::Manager::new()) .wrap(authorization.clone()) + .wrap(middleware::authentication::Manager::new()) .wrap(Cors::permissive()) .service( web::scope("/health_check").service(routes::health_check) From be1cb818a35f8743bbddde63dfcb833809441455 Mon Sep 17 00:00:00 2001 From: petru Date: Sat, 17 Feb 2024 17:56:54 +0200 Subject: [PATCH 09/24] 30-access-policies two authentication managers in one bowl --- src/middleware/authentication/mod.rs | 99 ++++++++++++++++++++++------ src/middleware/mod.rs | 1 - src/middleware/trydirect.rs | 56 ---------------- 3 files changed, 79 insertions(+), 77 deletions(-) delete mode 100644 src/middleware/trydirect.rs diff --git a/src/middleware/authentication/mod.rs b/src/middleware/authentication/mod.rs index 4a1851e3..1b79f1c3 100644 --- a/src/middleware/authentication/mod.rs +++ b/src/middleware/authentication/mod.rs @@ -1,24 +1,34 @@ -use crate::helpers::JsonResponse; -use crate::models::Client; +use crate::{ + helpers::JsonResponse, + models, + forms, + configuration::Settings, +}; use actix_http::header::CONTENT_LENGTH; -use actix_web::web::BytesMut; -use actix_web::HttpMessage; -use futures::future::{FutureExt, LocalBoxFuture}; -use futures::lock::Mutex; -use futures::task::{Context, Poll}; -use futures::StreamExt; +use futures::{ + future::{FutureExt, LocalBoxFuture}, + lock::Mutex, + task::{Context, Poll}, + StreamExt, +}; use hmac::{Hmac, Mac}; use sha2::Sha256; -use std::future::{ready, Ready}; -use std::str::FromStr; -use std::sync::Arc; +use std::{ + future::{ready, Ready}, + str::FromStr, + sync::Arc, +}; use tracing::Instrument; - -use actix_web::{ - dev::{Service, ServiceRequest, ServiceResponse, Transform}, +use actix_web::{}; +use reqwest::header::{ACCEPT, CONTENT_TYPE}; +use actix_web::{ + web::BytesMut, + HttpMessage, + web, + Error, + dev::{ServiceRequest, Service, ServiceResponse, Transform}, error::ErrorBadRequest, http::header::HeaderName, - web, Error, }; use sqlx::{Pool, Postgres}; @@ -76,7 +86,7 @@ where let authorization = get_header::(&req, "authorization")?; let client_id = get_header::(&req, "stacker-id")?; if authorization.is_some() { - //try_authorize_bearer(); //todo + try_authorize_bearer(&mut req, authorization.unwrap()).await?; } else if client_id.is_some() { try_authorize_id_hash(&mut req, client_id.unwrap()).await?; } else { @@ -98,7 +108,7 @@ where service.call(req).await } Err(msg) => Err(ErrorBadRequest( - JsonResponse::::build().set_msg(msg).to_string(), + JsonResponse::::build().set_msg(msg).to_string(), )), } }) @@ -127,11 +137,11 @@ where .map(|v| Some(v)) } -async fn db_fetch_client(db_pool: &Pool, client_id: i32) -> Result { //todo +async fn db_fetch_client(db_pool: &Pool, client_id: i32) -> Result { //todo let query_span = tracing::info_span!("Fetching the client by ID"); sqlx::query_as!( - Client, + models::Client, r#"SELECT id, user_id, secret FROM client c WHERE c.id = $1"#, client_id, ) @@ -174,6 +184,7 @@ async fn compute_body_hash(req: &mut ServiceRequest, client_secret: &[u8]) -> Re Ok(format!("{:x}", mac.finalize().into_bytes())) } +#[tracing::instrument(name = "try authorize. stacker-id header")] async fn try_authorize_id_hash(req: &mut ServiceRequest, client_id: i32) -> Result<(), String> { let header_hash = get_header::(&req, "stacker-hash")?; if header_hash.is_none() { @@ -182,7 +193,7 @@ async fn try_authorize_id_hash(req: &mut ServiceRequest, client_id: i32) -> Resu let header_hash = header_hash.unwrap(); let db_pool = req.app_data::>>().unwrap().get_ref(); - let client: Client = db_fetch_client(db_pool, client_id).await?; + let client: models::Client = db_fetch_client(db_pool, client_id).await?; if client.secret.is_none() { return Err("client is not active".to_string()); } @@ -211,3 +222,51 @@ async fn try_authorize_id_hash(req: &mut ServiceRequest, client_id: i32) -> Resu Ok(()) } + +#[tracing::instrument(name = "try authorize. Authorization header")] +async fn try_authorize_bearer(req: &mut ServiceRequest, authorization: String) -> Result<(), String> { + let settings = req.app_data::>().unwrap(); + let token = "abc"; //todo + let user = match fetch_user(settings.auth_url.as_str(), token).await { + Ok(user) => user, + Err(err) => { + return Err(format!("{}", err)); + } + }; //todo . process the err + + if req.extensions_mut().insert(Arc::new(user)).is_some() { + return Err("user already logged".to_string()); + } + + let accesscontrol_vals = actix_casbin_auth::CasbinVals { + subject: String::from("alice"), //todo username or anonymous + domain: None, + }; + if req.extensions_mut().insert(accesscontrol_vals).is_some() { + return Err("sth wrong with access control".to_string()); + } + + Ok(()) +} + +async fn fetch_user(auth_url: &str, token: &str) -> Result { + let client = reqwest::Client::new(); + let resp = client + .get(auth_url) + .bearer_auth(token) + .header(CONTENT_TYPE, "application/json") + .header(ACCEPT, "application/json") + .send() + .await + .map_err(|_err| "no resp from auth server".to_string())?; + + if !resp.status().is_success() { + return Err("401 Unauthorized".to_string()); + } + + resp + .json::() + .await + .map_err(|_err| "can't parse the response body".to_string())? + .try_into() +} diff --git a/src/middleware/mod.rs b/src/middleware/mod.rs index 5efc32ed..6d342506 100644 --- a/src/middleware/mod.rs +++ b/src/middleware/mod.rs @@ -1,3 +1,2 @@ pub mod authentication; -pub mod trydirect; pub mod authorization; diff --git a/src/middleware/trydirect.rs b/src/middleware/trydirect.rs deleted file mode 100644 index e9ce5eb8..00000000 --- a/src/middleware/trydirect.rs +++ /dev/null @@ -1,56 +0,0 @@ -use crate::{configuration::Settings, helpers::JsonResponse}; -use crate::models; -use crate::forms; -use actix_web::{web, dev::ServiceRequest, Error, HttpMessage}; -use actix_web_httpauth::extractors::bearer::BearerAuth; -use futures::future::{FutureExt}; -use reqwest::header::{ACCEPT, CONTENT_TYPE}; -use std::sync::Arc; - -#[tracing::instrument(name = "TryDirect bearer guard.")] -pub async fn bearer_guard( req: ServiceRequest, credentials: BearerAuth) -> Result { - let settings = req.app_data::>().unwrap(); - let token = credentials.token(); - let user = match fetch_user(settings.auth_url.as_str(), token).await { - Ok(user) => user, - Err(err) => { - return Err((JsonResponse::::build().unauthorized(err), req)); //todo anonymous - } - }; - - if req.extensions_mut().insert(Arc::new(user)).is_some() { - return Err((JsonResponse::::build().unauthorized("user already logged"), req)); //todo 500 internal error - } - - let accesscontrol_vals = actix_casbin_auth::CasbinVals { - subject: String::from("alice"), //todo username or anonymous - domain: None, - }; - if req.extensions_mut().insert(accesscontrol_vals).is_some() { - return Err((JsonResponse::::build().unauthorized("sth wrong with access control"), req)); //todo 500 internal error - } - - Ok(req) -} - -async fn fetch_user(auth_url: &str, token: &str) -> Result { - let client = reqwest::Client::new(); - let resp = client - .get(auth_url) - .bearer_auth(token) - .header(CONTENT_TYPE, "application/json") - .header(ACCEPT, "application/json") - .send() - .await - .map_err(|_err| "no resp from auth server".to_string())?; - - if !resp.status().is_success() { - return Err("401 Unauthorized".to_string()); - } - - resp - .json::() - .await - .map_err(|_err| "can't parse the response body".to_string())? - .try_into() -} From f0e3df50bfe94d296bde4a827cb231080ccb477c Mon Sep 17 00:00:00 2001 From: petru Date: Sun, 18 Feb 2024 08:25:30 +0200 Subject: [PATCH 10/24] 30-access-policies authorization.rs --- src/middleware/authorization.rs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/middleware/authorization.rs diff --git a/src/middleware/authorization.rs b/src/middleware/authorization.rs new file mode 100644 index 00000000..47601146 --- /dev/null +++ b/src/middleware/authorization.rs @@ -0,0 +1,32 @@ +use actix_casbin_auth::{ + CasbinService, + casbin::{ + DefaultModel, + CoreApi, + function_map::key_match2 + } +}; +use std::io::{Error, ErrorKind}; +use sqlx_adapter::SqlxAdapter; + +pub async fn try_new(db_connection_address: String) -> Result { + let m = DefaultModel::from_file("access_control.conf") + .await + .map_err(|err| Error::new(ErrorKind::Other, format!("{err:?}")))?; + let a = SqlxAdapter::new(db_connection_address, 8) + .await + .map_err(|err| Error::new(ErrorKind::Other, format!("{err:?}")))?; + + let mut casbin_service = CasbinService::new(m, a) + .await + .map_err(|err| Error::new(ErrorKind::Other, format!("{err:?}")))?; + + casbin_service + .write() + .await + .get_role_manager() + .write() + .matching_fn(Some(key_match2), None); + + Ok(casbin_service) +} From 626baec4f5f098ad59d83cbd99e5d67342606c15 Mon Sep 17 00:00:00 2001 From: petru Date: Sun, 18 Feb 2024 08:51:31 +0200 Subject: [PATCH 11/24] 30-access-policies --- src/middleware/authentication/manager.rs | 37 ++++++++ .../authentication/manager_middleware.rs | 58 ++++++++++++ src/middleware/authentication/mod.rs | 91 ++----------------- 3 files changed, 102 insertions(+), 84 deletions(-) create mode 100644 src/middleware/authentication/manager.rs create mode 100644 src/middleware/authentication/manager_middleware.rs diff --git a/src/middleware/authentication/manager.rs b/src/middleware/authentication/manager.rs new file mode 100644 index 00000000..2b8e09de --- /dev/null +++ b/src/middleware/authentication/manager.rs @@ -0,0 +1,37 @@ +use crate::middleware::authentication::*; + +use std::sync::Arc; +use std::future::{ready, Ready}; +use futures::lock::Mutex; + +use actix_web::{ + Error, + dev::{Service, ServiceRequest, ServiceResponse, Transform}, +}; + +pub struct Manager {} + +impl Manager { + pub fn new() -> Self { + Self {} + } +} + +impl Transform for Manager +where + S: Service, Error = Error> + 'static, + S::Future: 'static, + B: 'static, +{ + type Response = ServiceResponse; + type Error = Error; + type InitError = (); + type Transform = ManagerMiddleware; + type Future = Ready>; + + fn new_transform(&self, service: S) -> Self::Future { + ready(Ok(ManagerMiddleware { + service: Arc::new(Mutex::new(service)), + })) + } +} diff --git a/src/middleware/authentication/manager_middleware.rs b/src/middleware/authentication/manager_middleware.rs new file mode 100644 index 00000000..67ecbf7d --- /dev/null +++ b/src/middleware/authentication/manager_middleware.rs @@ -0,0 +1,58 @@ +use crate::middleware::authentication::*; + +pub struct ManagerMiddleware { + pub service: Arc>, +} + +impl Service for ManagerMiddleware +where + S: Service, Error = Error> + 'static, + S::Future: 'static, + B: 'static, +{ + type Response = ServiceResponse; + type Error = S::Error; + type Future = LocalBoxFuture<'static, Result, Error>>; + + fn poll_ready(&self, ctx: &mut Context<'_>) -> Poll> { + self.service + .try_lock() + .expect("Authentication ManagerMiddleware was called allready") + .poll_ready(ctx) + } + + fn call(&self, mut req: ServiceRequest) -> Self::Future { + let service = self.service.clone(); + async move { + let authorization = get_header::(&req, "authorization")?; + let client_id = get_header::(&req, "stacker-id")?; + if authorization.is_some() { + try_authorize_bearer(&mut req, authorization.unwrap()).await?; + } else if client_id.is_some() { + try_authorize_id_hash(&mut req, client_id.unwrap()).await?; + } else { + let accesscontrol_vals = actix_casbin_auth::CasbinVals { + subject: "anonym".to_string(), + domain: None, + }; + if req.extensions_mut().insert(accesscontrol_vals).is_some() { + return Err("sth wrong with access control".to_string()); + } + } + + Ok(req) + } + .then(|req: Result| async move { + match req { + Ok(req) => { + let service = service.lock().await; + service.call(req).await + } + Err(msg) => Err(ErrorBadRequest( + JsonResponse::::build().set_msg(msg).to_string(), + )), + } + }) + .boxed_local() + } +} diff --git a/src/middleware/authentication/mod.rs b/src/middleware/authentication/mod.rs index 1b79f1c3..36986c56 100644 --- a/src/middleware/authentication/mod.rs +++ b/src/middleware/authentication/mod.rs @@ -1,3 +1,9 @@ +mod manager; +mod manager_middleware; + +pub use manager::*; +pub use manager_middleware::*; + use crate::{ helpers::JsonResponse, models, @@ -32,90 +38,6 @@ use actix_web::{ }; use sqlx::{Pool, Postgres}; -pub struct Manager {} - -impl Manager { - pub fn new() -> Self { - Self {} - } -} - -impl Transform for Manager -where - S: Service, Error = Error> + 'static, - S::Future: 'static, - B: 'static, -{ - type Response = ServiceResponse; - type Error = Error; - type InitError = (); - type Transform = ManagerMiddleware; - type Future = Ready>; - - fn new_transform(&self, service: S) -> Self::Future { - ready(Ok(ManagerMiddleware { - service: Arc::new(Mutex::new(service)), - })) - } -} - -pub struct ManagerMiddleware { - service: Arc>, -} - -impl Service for ManagerMiddleware -where - S: Service, Error = Error> + 'static, - S::Future: 'static, - B: 'static, -{ - type Response = ServiceResponse; - type Error = S::Error; - type Future = LocalBoxFuture<'static, Result, Error>>; - - fn poll_ready(&self, ctx: &mut Context<'_>) -> Poll> { - self.service - .try_lock() - .expect("Authentication ManagerMiddleware was called allready") - .poll_ready(ctx) - } - - fn call(&self, mut req: ServiceRequest) -> Self::Future { - let service = self.service.clone(); - async move { - let authorization = get_header::(&req, "authorization")?; - let client_id = get_header::(&req, "stacker-id")?; - if authorization.is_some() { - try_authorize_bearer(&mut req, authorization.unwrap()).await?; - } else if client_id.is_some() { - try_authorize_id_hash(&mut req, client_id.unwrap()).await?; - } else { - let accesscontrol_vals = actix_casbin_auth::CasbinVals { - subject: "anonym".to_string(), - domain: None, - }; - if req.extensions_mut().insert(accesscontrol_vals).is_some() { - return Err("sth wrong with access control".to_string()); - } - } - - Ok(req) - } - .then(|req: Result| async move { - match req { - Ok(req) => { - let service = service.lock().await; - service.call(req).await - } - Err(msg) => Err(ErrorBadRequest( - JsonResponse::::build().set_msg(msg).to_string(), - )), - } - }) - .boxed_local() - } -} - fn get_header(req: &ServiceRequest, header_name: &'static str) -> Result, String> where T: FromStr, @@ -270,3 +192,4 @@ async fn fetch_user(auth_url: &str, token: &str) -> Result .map_err(|_err| "can't parse the response body".to_string())? .try_into() } + From 1820776afe98d894731ee4779d19d622252a58b3 Mon Sep 17 00:00:00 2001 From: petru Date: Mon, 19 Feb 2024 17:59:02 +0200 Subject: [PATCH 12/24] 30-access-policies refactor --- src/middleware/authentication/getheader.rs | 24 +++ .../authentication/manager_middleware.rs | 20 +- .../authentication/method/f_hmac.rs | 102 +++++++++ .../authentication/method/f_oauth.rs | 60 ++++++ src/middleware/authentication/method/mod.rs | 5 + src/middleware/authentication/mod.rs | 193 +----------------- 6 files changed, 207 insertions(+), 197 deletions(-) create mode 100644 src/middleware/authentication/getheader.rs create mode 100644 src/middleware/authentication/method/f_hmac.rs create mode 100644 src/middleware/authentication/method/f_oauth.rs create mode 100644 src/middleware/authentication/method/mod.rs diff --git a/src/middleware/authentication/getheader.rs b/src/middleware/authentication/getheader.rs new file mode 100644 index 00000000..d8104001 --- /dev/null +++ b/src/middleware/authentication/getheader.rs @@ -0,0 +1,24 @@ +use actix_web::{ http::header::HeaderName, dev::ServiceRequest}; +use std::str::FromStr; + +pub fn get_header(req: &ServiceRequest, header_name: &'static str) -> Result, String> +where + T: FromStr, +{ + let header_value = req + .headers() + .get(HeaderName::from_static(header_name)); + + if header_value.is_none() { + return Ok(None); + } + + header_value + .unwrap() + .to_str() + .map_err(|_| format!("header {header_name} can't be converted to string"))? + .parse::() + .map_err(|_| format!("header {header_name} has wrong type")) + .map(|v| Some(v)) +} + diff --git a/src/middleware/authentication/manager_middleware.rs b/src/middleware/authentication/manager_middleware.rs index 67ecbf7d..8faa9db7 100644 --- a/src/middleware/authentication/manager_middleware.rs +++ b/src/middleware/authentication/manager_middleware.rs @@ -1,4 +1,9 @@ use crate::middleware::authentication::*; +use actix_web::{error::ErrorBadRequest, HttpMessage, Error, dev::{ServiceRequest, ServiceResponse, Service}}; +use crate::helpers::JsonResponse; +use futures::{task::{Poll, Context}, future::{FutureExt, LocalBoxFuture}, lock::Mutex}; +use crate::models; +use std::sync::Arc; pub struct ManagerMiddleware { pub service: Arc>, @@ -24,13 +29,14 @@ where fn call(&self, mut req: ServiceRequest) -> Self::Future { let service = self.service.clone(); async move { - let authorization = get_header::(&req, "authorization")?; - let client_id = get_header::(&req, "stacker-id")?; - if authorization.is_some() { - try_authorize_bearer(&mut req, authorization.unwrap()).await?; - } else if client_id.is_some() { - try_authorize_id_hash(&mut req, client_id.unwrap()).await?; - } else { + /* + method::try_oauth(&mut req).await? + || method::try_hmac(&mut req).await? + || method::anonym(&mut req); //todo + */ + + if (!(method::try_oauth(&mut req).await? || method::try_hmac(&mut req).await?)) + { let accesscontrol_vals = actix_casbin_auth::CasbinVals { subject: "anonym".to_string(), domain: None, diff --git a/src/middleware/authentication/method/f_hmac.rs b/src/middleware/authentication/method/f_hmac.rs new file mode 100644 index 00000000..998a237f --- /dev/null +++ b/src/middleware/authentication/method/f_hmac.rs @@ -0,0 +1,102 @@ +use hmac::{Hmac, Mac}; +use sha2::Sha256; +use sqlx::{Pool, Postgres}; +use tracing::Instrument; +use std::sync::Arc; +use crate::models; +use actix_web::{web, dev::ServiceRequest, HttpMessage}; +use crate::middleware::authentication::get_header; //todo move to helpers +use actix_http::header::CONTENT_LENGTH; +use futures::StreamExt; + +async fn db_fetch_client(db_pool: &Pool, client_id: i32) -> Result { //todo + let query_span = tracing::info_span!("Fetching the client by ID"); + + sqlx::query_as!( + models::Client, + r#"SELECT id, user_id, secret FROM client c WHERE c.id = $1"#, + client_id, + ) + .fetch_one(db_pool) + .instrument(query_span) + .await + .map_err(|err| { + match err { + sqlx::Error::RowNotFound => "the client is not found".to_string(), + e => { + tracing::error!("Failed to execute fetch query: {:?}", e); + String::new() + } + } + }) +} + +async fn compute_body_hash(req: &mut ServiceRequest, client_secret: &[u8]) -> Result { + let content_length: usize = get_header(req, CONTENT_LENGTH.as_str())?.unwrap(); + let mut body = web::BytesMut::with_capacity(content_length); + let mut payload = req.take_payload(); + while let Some(chunk) = payload.next().await { + body.extend_from_slice(&chunk.expect("can't unwrap the chunk")); + } + + let mut mac = + match Hmac::::new_from_slice(client_secret) { + Ok(mac) => mac, + Err(err) => { + tracing::error!("error generating hmac {err:?}"); + return Err("".to_string()); + } + }; + + mac.update(body.as_ref()); + let (_, mut payload) = actix_http::h1::Payload::create(true); + payload.unread_data(body.into()); + req.set_payload(payload.into()); + + Ok(format!("{:x}", mac.finalize().into_bytes())) +} + +#[tracing::instrument(name = "try authorize. stacker-id header")] +pub async fn try_hmac(req: &mut ServiceRequest) -> Result { + let client_id = get_header::(&req, "stacker-id")?; + if client_id.is_none() { + return Ok(false); + } + let client_id = client_id.unwrap(); + + let header_hash = get_header::(&req, "stacker-hash")?; + if header_hash.is_none() { + return Err("stacker-hash header is not set".to_string()); + } //todo + let header_hash = header_hash.unwrap(); + + let db_pool = req.app_data::>>().unwrap().get_ref(); + let client: models::Client = db_fetch_client(db_pool, client_id).await?; + if client.secret.is_none() { + return Err("client is not active".to_string()); + } + + let client_secret = client.secret.as_ref().unwrap().as_bytes(); + let body_hash = compute_body_hash(req, client_secret).await?; + if header_hash != body_hash { + return Err("hash is wrong".to_string()); + } + + match req.extensions_mut().insert(Arc::new(client)) { + Some(_) => { + tracing::error!("client middleware already called once"); + return Err("".to_string()); + } + None => {} + } + + let accesscontrol_vals = actix_casbin_auth::CasbinVals { + subject: client_id.to_string(), + domain: None, + }; + if req.extensions_mut().insert(accesscontrol_vals).is_some() { + return Err("sth wrong with access control".to_string()); + } + + Ok(true) +} diff --git a/src/middleware/authentication/method/f_oauth.rs b/src/middleware/authentication/method/f_oauth.rs new file mode 100644 index 00000000..02b20243 --- /dev/null +++ b/src/middleware/authentication/method/f_oauth.rs @@ -0,0 +1,60 @@ +use crate::middleware::authentication::get_header; +use actix_web::{web, dev::{ServiceRequest}, HttpMessage}; +use crate::configuration::Settings; +use crate::models; +use crate::forms; +use reqwest::header::{ACCEPT, CONTENT_TYPE}; +use std::sync::Arc; + +#[tracing::instrument(name = "try authorize. Authorization header")] +pub async fn try_oauth(req: &mut ServiceRequest) -> Result { + let authentication = get_header::(&req, "authorization")?; //todo + if authentication.is_none() { + return Ok(false); + } + + let settings = req.app_data::>().unwrap(); + let token = "abc"; //todo + let user = match fetch_user(settings.auth_url.as_str(), token).await { + Ok(user) => user, + Err(err) => { + return Err(format!("{}", err)); + } + }; //todo . process the err + + if req.extensions_mut().insert(Arc::new(user)).is_some() { + return Err("user already logged".to_string()); + } + + let accesscontrol_vals = actix_casbin_auth::CasbinVals { + subject: String::from("alice"), //todo username or anonymous + domain: None, + }; + if req.extensions_mut().insert(accesscontrol_vals).is_some() { + return Err("sth wrong with access control".to_string()); + } + + Ok(true) +} + +async fn fetch_user(auth_url: &str, token: &str) -> Result { + let client = reqwest::Client::new(); + let resp = client + .get(auth_url) + .bearer_auth(token) + .header(CONTENT_TYPE, "application/json") + .header(ACCEPT, "application/json") + .send() + .await + .map_err(|_err| "no resp from auth server".to_string())?; + + if !resp.status().is_success() { + return Err("401 Unauthorized".to_string()); + } + + resp + .json::() + .await + .map_err(|_err| "can't parse the response body".to_string())? + .try_into() +} diff --git a/src/middleware/authentication/method/mod.rs b/src/middleware/authentication/method/mod.rs new file mode 100644 index 00000000..5d82a318 --- /dev/null +++ b/src/middleware/authentication/method/mod.rs @@ -0,0 +1,5 @@ +mod f_oauth; +mod f_hmac; + +pub use f_oauth::try_oauth; +pub use f_hmac::try_hmac; diff --git a/src/middleware/authentication/mod.rs b/src/middleware/authentication/mod.rs index 36986c56..5338d6dd 100644 --- a/src/middleware/authentication/mod.rs +++ b/src/middleware/authentication/mod.rs @@ -1,195 +1,8 @@ +mod getheader; mod manager; mod manager_middleware; +mod method; +pub use getheader::*; pub use manager::*; pub use manager_middleware::*; - -use crate::{ - helpers::JsonResponse, - models, - forms, - configuration::Settings, -}; -use actix_http::header::CONTENT_LENGTH; -use futures::{ - future::{FutureExt, LocalBoxFuture}, - lock::Mutex, - task::{Context, Poll}, - StreamExt, -}; -use hmac::{Hmac, Mac}; -use sha2::Sha256; -use std::{ - future::{ready, Ready}, - str::FromStr, - sync::Arc, -}; -use tracing::Instrument; -use actix_web::{}; -use reqwest::header::{ACCEPT, CONTENT_TYPE}; -use actix_web::{ - web::BytesMut, - HttpMessage, - web, - Error, - dev::{ServiceRequest, Service, ServiceResponse, Transform}, - error::ErrorBadRequest, - http::header::HeaderName, -}; -use sqlx::{Pool, Postgres}; - -fn get_header(req: &ServiceRequest, header_name: &'static str) -> Result, String> -where - T: FromStr, -{ - let header_value = req - .headers() - .get(HeaderName::from_static(header_name)); - - if header_value.is_none() { - return Ok(None); - } - - header_value - .unwrap() - .to_str() - .map_err(|_| format!("header {header_name} can't be converted to string"))? - .parse::() - .map_err(|_| format!("header {header_name} has wrong type")) - .map(|v| Some(v)) -} - -async fn db_fetch_client(db_pool: &Pool, client_id: i32) -> Result { //todo - let query_span = tracing::info_span!("Fetching the client by ID"); - - sqlx::query_as!( - models::Client, - r#"SELECT id, user_id, secret FROM client c WHERE c.id = $1"#, - client_id, - ) - .fetch_one(db_pool) - .instrument(query_span) - .await - .map_err(|err| { - match err { - sqlx::Error::RowNotFound => "the client is not found".to_string(), - e => { - tracing::error!("Failed to execute fetch query: {:?}", e); - String::new() - } - } - }) -} - -async fn compute_body_hash(req: &mut ServiceRequest, client_secret: &[u8]) -> Result { - let content_length: usize = get_header(req, CONTENT_LENGTH.as_str())?.unwrap(); - let mut body = BytesMut::with_capacity(content_length); - let mut payload = req.take_payload(); - while let Some(chunk) = payload.next().await { - body.extend_from_slice(&chunk.expect("can't unwrap the chunk")); - } - - let mut mac = - match Hmac::::new_from_slice(client_secret) { - Ok(mac) => mac, - Err(err) => { - tracing::error!("error generating hmac {err:?}"); - return Err("".to_string()); - } - }; - - mac.update(body.as_ref()); - let (_, mut payload) = actix_http::h1::Payload::create(true); - payload.unread_data(body.into()); - req.set_payload(payload.into()); - - Ok(format!("{:x}", mac.finalize().into_bytes())) -} - -#[tracing::instrument(name = "try authorize. stacker-id header")] -async fn try_authorize_id_hash(req: &mut ServiceRequest, client_id: i32) -> Result<(), String> { - let header_hash = get_header::(&req, "stacker-hash")?; - if header_hash.is_none() { - return Err("stacker-hash header is not set".to_string()); - } //todo - let header_hash = header_hash.unwrap(); - - let db_pool = req.app_data::>>().unwrap().get_ref(); - let client: models::Client = db_fetch_client(db_pool, client_id).await?; - if client.secret.is_none() { - return Err("client is not active".to_string()); - } - - let client_secret = client.secret.as_ref().unwrap().as_bytes(); - let body_hash = compute_body_hash(req, client_secret).await?; - if header_hash != body_hash { - return Err("hash is wrong".to_string()); - } - - match req.extensions_mut().insert(Arc::new(client)) { - Some(_) => { - tracing::error!("client middleware already called once"); - return Err("".to_string()); - } - None => {} - } - - let accesscontrol_vals = actix_casbin_auth::CasbinVals { - subject: client_id.to_string(), - domain: None, - }; - if req.extensions_mut().insert(accesscontrol_vals).is_some() { - return Err("sth wrong with access control".to_string()); - } - - Ok(()) -} - -#[tracing::instrument(name = "try authorize. Authorization header")] -async fn try_authorize_bearer(req: &mut ServiceRequest, authorization: String) -> Result<(), String> { - let settings = req.app_data::>().unwrap(); - let token = "abc"; //todo - let user = match fetch_user(settings.auth_url.as_str(), token).await { - Ok(user) => user, - Err(err) => { - return Err(format!("{}", err)); - } - }; //todo . process the err - - if req.extensions_mut().insert(Arc::new(user)).is_some() { - return Err("user already logged".to_string()); - } - - let accesscontrol_vals = actix_casbin_auth::CasbinVals { - subject: String::from("alice"), //todo username or anonymous - domain: None, - }; - if req.extensions_mut().insert(accesscontrol_vals).is_some() { - return Err("sth wrong with access control".to_string()); - } - - Ok(()) -} - -async fn fetch_user(auth_url: &str, token: &str) -> Result { - let client = reqwest::Client::new(); - let resp = client - .get(auth_url) - .bearer_auth(token) - .header(CONTENT_TYPE, "application/json") - .header(ACCEPT, "application/json") - .send() - .await - .map_err(|_err| "no resp from auth server".to_string())?; - - if !resp.status().is_success() { - return Err("401 Unauthorized".to_string()); - } - - resp - .json::() - .await - .map_err(|_err| "can't parse the response body".to_string())? - .try_into() -} - From 5330ad931ecc37b056539d50ab12447cae404f66 Mon Sep 17 00:00:00 2001 From: petru Date: Tue, 20 Feb 2024 07:40:33 +0200 Subject: [PATCH 13/24] 30-access-policies anonym logic separated --- .../authentication/manager_middleware.rs | 15 +-------------- src/middleware/authentication/method/f_anonym.rs | 15 +++++++++++++++ src/middleware/authentication/method/f_hmac.rs | 2 +- src/middleware/authentication/method/f_oauth.rs | 2 +- src/middleware/authentication/method/mod.rs | 2 ++ 5 files changed, 20 insertions(+), 16 deletions(-) create mode 100644 src/middleware/authentication/method/f_anonym.rs diff --git a/src/middleware/authentication/manager_middleware.rs b/src/middleware/authentication/manager_middleware.rs index 8faa9db7..0a72c8d3 100644 --- a/src/middleware/authentication/manager_middleware.rs +++ b/src/middleware/authentication/manager_middleware.rs @@ -29,22 +29,9 @@ where fn call(&self, mut req: ServiceRequest) -> Self::Future { let service = self.service.clone(); async move { - /* method::try_oauth(&mut req).await? || method::try_hmac(&mut req).await? - || method::anonym(&mut req); //todo - */ - - if (!(method::try_oauth(&mut req).await? || method::try_hmac(&mut req).await?)) - { - let accesscontrol_vals = actix_casbin_auth::CasbinVals { - subject: "anonym".to_string(), - domain: None, - }; - if req.extensions_mut().insert(accesscontrol_vals).is_some() { - return Err("sth wrong with access control".to_string()); - } - } + || method::anonym(&mut req)?; Ok(req) } diff --git a/src/middleware/authentication/method/f_anonym.rs b/src/middleware/authentication/method/f_anonym.rs new file mode 100644 index 00000000..fa7c2888 --- /dev/null +++ b/src/middleware/authentication/method/f_anonym.rs @@ -0,0 +1,15 @@ +use actix_web::dev::ServiceRequest; +use actix_web::HttpMessage; + +#[tracing::instrument(name = "authenticate as anonym")] +pub fn anonym(req: &mut ServiceRequest) -> Result { + let accesscontrol_vals = actix_casbin_auth::CasbinVals { + subject: "anonym".to_string(), + domain: None, + }; + if req.extensions_mut().insert(accesscontrol_vals).is_some() { + return Err("sth wrong with access control".to_string()); + } + + Ok(true) +} diff --git a/src/middleware/authentication/method/f_hmac.rs b/src/middleware/authentication/method/f_hmac.rs index 998a237f..e385f8f7 100644 --- a/src/middleware/authentication/method/f_hmac.rs +++ b/src/middleware/authentication/method/f_hmac.rs @@ -56,7 +56,7 @@ async fn compute_body_hash(req: &mut ServiceRequest, client_secret: &[u8]) -> Re Ok(format!("{:x}", mac.finalize().into_bytes())) } -#[tracing::instrument(name = "try authorize. stacker-id header")] +#[tracing::instrument(name = "try authenticate via hmac")] pub async fn try_hmac(req: &mut ServiceRequest) -> Result { let client_id = get_header::(&req, "stacker-id")?; if client_id.is_none() { diff --git a/src/middleware/authentication/method/f_oauth.rs b/src/middleware/authentication/method/f_oauth.rs index 02b20243..5566f49b 100644 --- a/src/middleware/authentication/method/f_oauth.rs +++ b/src/middleware/authentication/method/f_oauth.rs @@ -6,7 +6,7 @@ use crate::forms; use reqwest::header::{ACCEPT, CONTENT_TYPE}; use std::sync::Arc; -#[tracing::instrument(name = "try authorize. Authorization header")] +#[tracing::instrument(name = "try authenticate via bearer")] pub async fn try_oauth(req: &mut ServiceRequest) -> Result { let authentication = get_header::(&req, "authorization")?; //todo if authentication.is_none() { diff --git a/src/middleware/authentication/method/mod.rs b/src/middleware/authentication/method/mod.rs index 5d82a318..3d55881a 100644 --- a/src/middleware/authentication/method/mod.rs +++ b/src/middleware/authentication/method/mod.rs @@ -1,5 +1,7 @@ mod f_oauth; +mod f_anonym; mod f_hmac; pub use f_oauth::try_oauth; +pub use f_anonym::anonym; pub use f_hmac::try_hmac; From 44c28efbe555b35bfe6976947aa0cc68412322e0 Mon Sep 17 00:00:00 2001 From: petru Date: Tue, 20 Feb 2024 17:18:04 +0200 Subject: [PATCH 14/24] 30-access-policies removed http authentication --- Cargo.lock | 219 ++++++++---------- Cargo.toml | 1 - .../authentication/manager_middleware.rs | 2 +- .../authentication/method/f_oauth.rs | 1 + src/startup.rs | 1 - 5 files changed, 104 insertions(+), 120 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 269e5798..da5e64ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -56,7 +56,7 @@ dependencies = [ "actix-rt", "actix-service", "actix-utils", - "ahash 0.8.7", + "ahash 0.8.9", "base64 0.21.7", "bitflags 2.4.2", "brotli", @@ -92,7 +92,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" dependencies = [ "quote", - "syn 2.0.48", + "syn 2.0.50", ] [[package]] @@ -171,7 +171,7 @@ dependencies = [ "actix-service", "actix-utils", "actix-web-codegen", - "ahash 0.8.7", + "ahash 0.8.9", "bytes", "bytestring", "cfg-if", @@ -205,22 +205,7 @@ dependencies = [ "actix-router", "proc-macro2", "quote", - "syn 2.0.48", -] - -[[package]] -name = "actix-web-httpauth" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d613edf08a42ccc6864c941d30fe14e1b676a77d16f1dbadc1174d065a0a775" -dependencies = [ - "actix-utils", - "actix-web", - "base64 0.21.7", - "futures-core", - "futures-util", - "log", - "pin-project-lite", + "syn 2.0.50", ] [[package]] @@ -240,9 +225,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.7.7" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ "getrandom 0.2.12", "once_cell", @@ -251,9 +236,9 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.7" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" +checksum = "d713b3834d76b85304d4d525563c1276e2e30dc97cc67bfb4585a4a29fc2c89f" dependencies = [ "cfg-if", "const-random", @@ -358,9 +343,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.11" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" +checksum = "96b09b5178381e0874812a9b157f7fe84982617e48f71f4e3235482775e5b540" dependencies = [ "anstyle", "anstyle-parse", @@ -406,9 +391,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.79" +version = "1.0.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" +checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" [[package]] name = "assert-json-diff" @@ -438,7 +423,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f28243a43d821d11341ab73c80bed182dc015c514b951616cf79bd4af39af0c3" dependencies = [ "concurrent-queue", - "event-listener 5.0.0", + "event-listener 5.1.0", "event-listener-strategy 0.5.0", "futures-core", "pin-project-lite", @@ -516,7 +501,7 @@ dependencies = [ "futures-io", "futures-lite 2.2.0", "parking", - "polling 3.4.0", + "polling 3.5.0", "rustix 0.38.31", "slab", "tracing", @@ -569,7 +554,7 @@ checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.50", ] [[package]] @@ -708,9 +693,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "d32a994c2b3ca201d9b263612a374263f05e7adde37c4707f693dcd375076d1f" [[package]] name = "bytecount" @@ -844,9 +829,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.0" +version = "4.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80c21025abd42669a92efc996ef13cfb2c5c627858421ea58d5c3b331a6c134f" +checksum = "c918d541ef2913577a0f9566e9ce27cb35b6df072075769e0b26cb5a554520da" dependencies = [ "clap_builder", "clap_derive", @@ -854,9 +839,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.0" +version = "4.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "458bf1f341769dfcf849846f65dffdf9146daa56bcd2a47cb4e1de9915567c99" +checksum = "9f3e7391dad68afb0c2ede1bf619f579a3dc9c2ec67f089baa397123a2f3d1eb" dependencies = [ "anstream", "anstyle", @@ -873,7 +858,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.50", ] [[package]] @@ -1001,9 +986,9 @@ checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" dependencies = [ "cfg-if", ] @@ -1161,11 +1146,11 @@ dependencies = [ [[package]] name = "derive_builder" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "660047478bc508c0fde22c868991eec0c40a63e48d610befef466d48e2bee574" +checksum = "8f59169f400d8087f238c5c0c7db6a28af18681717f3b623227d92f397e938c7" dependencies = [ - "derive_builder_macro 0.13.0", + "derive_builder_macro 0.13.1", ] [[package]] @@ -1182,9 +1167,9 @@ dependencies = [ [[package]] name = "derive_builder_core" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b217e6dd1011a54d12f3b920a411b5abd44b1716ecfe94f5f2f2f7b52e08ab7" +checksum = "a4ec317cc3e7ef0928b0ca6e4a634a4d6c001672ae210438cf114a83e56b018d" dependencies = [ "darling", "proc-macro2", @@ -1204,11 +1189,11 @@ dependencies = [ [[package]] name = "derive_builder_macro" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5f77d7e20ac9153428f7ca14a88aba652adfc7a0ef0a06d654386310ef663b" +checksum = "870368c3fb35b8031abb378861d4460f573b92238ec2152c927a21f77e3e0127" dependencies = [ - "derive_builder_core 0.13.0", + "derive_builder_core 0.13.1", "syn 1.0.109", ] @@ -1283,8 +1268,8 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e366950e7785fe0e404901a2b4e5c09ebd6656767f0c2167e34c5068ce0cc2d" dependencies = [ - "derive_builder 0.13.0", - "indexmap 2.2.2", + "derive_builder 0.13.1", + "indexmap 2.2.3", "serde", "serde_yaml", ] @@ -1374,9 +1359,9 @@ dependencies = [ [[package]] name = "event-listener" -version = "5.0.0" +version = "5.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b72557800024fabbaa2449dd4bf24e37b93702d457a4d4f2b0dd1f0f039f20c1" +checksum = "b7ad6fd685ce13acd6d9541a30f6db6567a7a24c9ffd4ba2955d29e3f22c8b27" dependencies = [ "concurrent-queue", "parking", @@ -1399,7 +1384,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "feedafcaa9b749175d5ac357452a9d41ea2911da598fde46ce1fe02c37751291" dependencies = [ - "event-listener 5.0.0", + "event-listener 5.1.0", "pin-project-lite", ] @@ -1606,7 +1591,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.50", ] [[package]] @@ -1713,7 +1698,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 2.2.2", + "indexmap 2.2.3", "slab", "tokio", "tokio-util", @@ -1726,7 +1711,7 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" dependencies = [ - "ahash 0.7.7", + "ahash 0.7.8", ] [[package]] @@ -1735,7 +1720,7 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "ahash 0.7.7", + "ahash 0.7.8", ] [[package]] @@ -1744,7 +1729,7 @@ version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" dependencies = [ - "ahash 0.8.7", + "ahash 0.8.9", "allocator-api2", ] @@ -1768,9 +1753,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0c62115964e08cb8039170eb33c1d0e2388a256930279edca206fff675f82c3" +checksum = "bd5256b483761cd23699d0da46cc6fd2ee3be420bbe6d020ae4a091e70b7e9fd" [[package]] name = "hex" @@ -1949,9 +1934,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.2" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "824b2ae422412366ba479e8111fd301f7b5faece8149317bb81925979a53f520" +checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177" dependencies = [ "equivalent", "hashbrown 0.14.3", @@ -2326,9 +2311,9 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "openssl" -version = "0.10.63" +version = "0.10.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15c9d69dd87a29568d4d017cfe8ec518706046a05184e5aea92d0af890b803c8" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" dependencies = [ "bitflags 2.4.2", "cfg-if", @@ -2347,7 +2332,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.50", ] [[package]] @@ -2358,9 +2343,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.99" +version = "0.9.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e1bf214306098e4832460f797824c05d25aacdf896f64a985fb0fd992454ae" +checksum = "ae94056a791d0e1217d18b6cbdccb02c61e3054fc69893607f4067e3bb0b1fd1" dependencies = [ "cc", "libc", @@ -2504,7 +2489,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.50", ] [[package]] @@ -2525,7 +2510,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap 2.2.2", + "indexmap 2.2.3", ] [[package]] @@ -2545,7 +2530,7 @@ checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.50", ] [[package]] @@ -2585,9 +2570,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "polling" @@ -2607,9 +2592,9 @@ dependencies = [ [[package]] name = "polling" -version = "3.4.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30054e72317ab98eddd8561db0f6524df3367636884b7b21b703e4b280a84a14" +checksum = "24f040dee2588b4963afb4e420540439d126f73fdacf4a9c486a96d840bac3c9" dependencies = [ "cfg-if", "concurrent-queue", @@ -2900,7 +2885,7 @@ version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6273372244d04a8a4b0bec080ea1e710403e88c5d9d83f9808b2bfa64f0982a" dependencies = [ - "ahash 0.8.7", + "ahash 0.8.9", "bitflags 2.4.2", "instant", "num-traits", @@ -2920,7 +2905,7 @@ checksum = "9db7f8dc4c9d48183a17ce550574c42995252b82d267eaca3fcd1b979159856c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.50", ] [[package]] @@ -2940,16 +2925,17 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.7" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", + "cfg-if", "getrandom 0.2.12", "libc", "spin 0.9.8", "untrusted 0.9.0", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2958,7 +2944,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98f2771d255fd99f0294f13249fecd0cae6e074f86b4197ec1f1689d537b44d3" dependencies = [ - "ahash 0.7.7", + "ahash 0.7.8", "hashbrown 0.11.2", ] @@ -3044,7 +3030,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" dependencies = [ "log", - "ring 0.17.7", + "ring 0.17.8", "rustls-webpki", "sct", ] @@ -3088,15 +3074,15 @@ version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring 0.17.7", + "ring 0.17.8", "untrusted 0.9.0", ] [[package]] name = "ryu" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" [[package]] name = "same-file" @@ -3128,7 +3114,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring 0.17.7", + "ring 0.17.8", "untrusted 0.9.0", ] @@ -3157,38 +3143,38 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.21" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" dependencies = [ "serde", ] [[package]] name = "serde" -version = "1.0.196" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.196" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.50", ] [[package]] name = "serde_json" -version = "1.0.113" +version = "1.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" +checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" dependencies = [ "itoa", "ryu", @@ -3274,11 +3260,11 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.9.31" +version = "0.9.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adf8a49373e98a4c5f0ceb5d05aa7c648d75f63774981ed95b7c7443bbd50c6e" +checksum = "8fd075d994154d4a774f95b51fb96bdc2832b0ea48425c92546073816cda1f2f" dependencies = [ - "indexmap 2.2.2", + "indexmap 2.2.3", "itoa", "ryu", "serde", @@ -3439,9 +3425,9 @@ dependencies = [ [[package]] name = "sqlx-adapter" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e39a25e18b8f9cd4f61b1653be67260d28dcd31b0bd8d3a08ed3ecbe2afa3b84" +checksum = "24fe30f13db95ad25c9b7480d9a3c8b1fabe42a9ebd670428fa56a7173281eaa" dependencies = [ "async-trait", "casbin", @@ -3455,7 +3441,7 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa8241483a83a3f33aa5fff7e7d9def398ff9990b2752b6c6112b83c6d246029" dependencies = [ - "ahash 0.7.7", + "ahash 0.7.8", "atoi 1.0.0", "base64 0.13.1", "bitflags 1.3.2", @@ -3510,7 +3496,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d84b0a3c3739e220d94b3239fd69fb1f74bc36e16643423bd99de3b43c21bfbd" dependencies = [ - "ahash 0.8.7", + "ahash 0.8.9", "atoi 2.0.0", "byteorder", "bytes", @@ -3526,7 +3512,7 @@ dependencies = [ "futures-util", "hashlink", "hex", - "indexmap 2.2.2", + "indexmap 2.2.3", "log", "memchr", "native-tls", @@ -3663,7 +3649,6 @@ dependencies = [ "actix-cors", "actix-http", "actix-web", - "actix-web-httpauth", "chrono", "clap", "config", @@ -3675,7 +3660,7 @@ dependencies = [ "futures-util", "glob", "hmac", - "indexmap 2.2.2", + "indexmap 2.2.3", "lapin", "rand 0.8.5", "regex", @@ -3749,9 +3734,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.48" +version = "2.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "74f1bdc9872430ce9b75da68329d1c1746faf50ffac5f19e02b71e37ff881ffb" dependencies = [ "proc-macro2", "quote", @@ -3826,22 +3811,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.56" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.56" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.50", ] [[package]] @@ -3958,7 +3943,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.50", ] [[package]] @@ -4055,7 +4040,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.50", ] [[package]] @@ -4064,7 +4049,7 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5c266b9ac83dedf0e0385ad78514949e6d89491269e7065bee51d2bb8ec7373" dependencies = [ - "ahash 0.8.7", + "ahash 0.8.9", "gethostname", "log", "serde", @@ -4320,7 +4305,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.50", "wasm-bindgen-shared", ] @@ -4354,7 +4339,7 @@ checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.50", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4381,7 +4366,7 @@ version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" dependencies = [ - "ring 0.17.7", + "ring 0.17.8", "untrusted 0.9.0", ] @@ -4640,7 +4625,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.50", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 20a127c1..56ef8125 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +33,6 @@ thiserror = "1.0" serde_valid = "0.16.3" serde_json = { version = "1.0.105", features = [] } serde_derive = "1.0.188" -actix-web-httpauth = "0.8.1" actix-cors = "0.6.4" tracing-actix-web = "0.7.7" regex = "1.10.2" diff --git a/src/middleware/authentication/manager_middleware.rs b/src/middleware/authentication/manager_middleware.rs index 0a72c8d3..7b9dc6b9 100644 --- a/src/middleware/authentication/manager_middleware.rs +++ b/src/middleware/authentication/manager_middleware.rs @@ -29,7 +29,7 @@ where fn call(&self, mut req: ServiceRequest) -> Self::Future { let service = self.service.clone(); async move { - method::try_oauth(&mut req).await? + let _ = method::try_oauth(&mut req).await? || method::try_hmac(&mut req).await? || method::anonym(&mut req)?; diff --git a/src/middleware/authentication/method/f_oauth.rs b/src/middleware/authentication/method/f_oauth.rs index 5566f49b..5befe353 100644 --- a/src/middleware/authentication/method/f_oauth.rs +++ b/src/middleware/authentication/method/f_oauth.rs @@ -9,6 +9,7 @@ use std::sync::Arc; #[tracing::instrument(name = "try authenticate via bearer")] pub async fn try_oauth(req: &mut ServiceRequest) -> Result { let authentication = get_header::(&req, "authorization")?; //todo + println!("{authentication:?}"); if authentication.is_none() { return Ok(false); } diff --git a/src/startup.rs b/src/startup.rs index 279044e6..5e57dc85 100644 --- a/src/startup.rs +++ b/src/startup.rs @@ -8,7 +8,6 @@ use actix_web::{ App, HttpServer, }; use crate::middleware; -use actix_web_httpauth::middleware::HttpAuthentication; use sqlx::{Pool, Postgres}; use std::net::TcpListener; use tracing_actix_web::TracingLogger; From 0e5901da64a4987dee929a45d5d93a874b6dcb3c Mon Sep 17 00:00:00 2001 From: petru Date: Tue, 20 Feb 2024 18:30:50 +0200 Subject: [PATCH 15/24] 30-access-policies Bearer token extract logic --- .../authentication/method/f_oauth.rs | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/middleware/authentication/method/f_oauth.rs b/src/middleware/authentication/method/f_oauth.rs index 5befe353..2b8ccb81 100644 --- a/src/middleware/authentication/method/f_oauth.rs +++ b/src/middleware/authentication/method/f_oauth.rs @@ -6,17 +6,30 @@ use crate::forms; use reqwest::header::{ACCEPT, CONTENT_TYPE}; use std::sync::Arc; +fn try_extract_token(authentication: String) -> Result { + let mut authentication_parts = authentication.splitn(2, ' '); + match authentication_parts.next() { + Some("Bearer") => {} + _ => return Err("Bearer missing scheme".to_string()) + } + let token = authentication_parts.next(); + if token.is_none() { + return Err("Empty bearer token".to_string()); + } + + Ok(token.unwrap().into()) +} + #[tracing::instrument(name = "try authenticate via bearer")] pub async fn try_oauth(req: &mut ServiceRequest) -> Result { - let authentication = get_header::(&req, "authorization")?; //todo - println!("{authentication:?}"); + let authentication = get_header::(&req, "authorization")?; if authentication.is_none() { return Ok(false); } + let token = try_extract_token(authentication.unwrap())?; let settings = req.app_data::>().unwrap(); - let token = "abc"; //todo - let user = match fetch_user(settings.auth_url.as_str(), token).await { + let user = match fetch_user(settings.auth_url.as_str(), &token).await { Ok(user) => user, Err(err) => { return Err(format!("{}", err)); From 35815f61cccae763bfce7221661fabde219b98a1 Mon Sep 17 00:00:00 2001 From: petru Date: Wed, 21 Feb 2024 16:36:36 +0200 Subject: [PATCH 16/24] 30-access-policies user_fetch improved --- .../authentication/method/f_oauth.rs | 18 ++++++++---------- src/routes/client/disable.rs | 2 ++ src/routes/client/enable.rs | 2 ++ src/routes/client/update.rs | 2 ++ 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/middleware/authentication/method/f_oauth.rs b/src/middleware/authentication/method/f_oauth.rs index 2b8ccb81..efe215c6 100644 --- a/src/middleware/authentication/method/f_oauth.rs +++ b/src/middleware/authentication/method/f_oauth.rs @@ -29,21 +29,19 @@ pub async fn try_oauth(req: &mut ServiceRequest) -> Result { let token = try_extract_token(authentication.unwrap())?; let settings = req.app_data::>().unwrap(); - let user = match fetch_user(settings.auth_url.as_str(), &token).await { - Ok(user) => user, - Err(err) => { - return Err(format!("{}", err)); - } - }; //todo . process the err + let user = fetch_user(settings.auth_url.as_str(), &token) + .await + .map_err(|err| format!("{err}"))?; + + let accesscontrol_vals = actix_casbin_auth::CasbinVals { + subject: user.id.clone(), + domain: None, + }; if req.extensions_mut().insert(Arc::new(user)).is_some() { return Err("user already logged".to_string()); } - let accesscontrol_vals = actix_casbin_auth::CasbinVals { - subject: String::from("alice"), //todo username or anonymous - domain: None, - }; if req.extensions_mut().insert(accesscontrol_vals).is_some() { return Err("sth wrong with access control".to_string()); } diff --git a/src/routes/client/disable.rs b/src/routes/client/disable.rs index 70d2a1cb..3c46fa65 100644 --- a/src/routes/client/disable.rs +++ b/src/routes/client/disable.rs @@ -15,6 +15,8 @@ pub async fn disable_handler( pg_pool: web::Data, path: web::Path<(i32,)>, ) -> Result { + //todo. the owner + //todo. add admin endpoint let client_id = path.0; let mut client = db::client::fetch(pg_pool.get_ref(), client_id) .await diff --git a/src/routes/client/enable.rs b/src/routes/client/enable.rs index c87fc445..ca36451c 100644 --- a/src/routes/client/enable.rs +++ b/src/routes/client/enable.rs @@ -16,6 +16,8 @@ pub async fn enable_handler( pg_pool: web::Data, path: web::Path<(i32,)>, ) -> Result { + //todo the owner + //todo add admin endpoint let client_id = path.0; let mut client = db::client::fetch(pg_pool.get_ref(), client_id) .await diff --git a/src/routes/client/update.rs b/src/routes/client/update.rs index 5f19de51..fe8db12e 100644 --- a/src/routes/client/update.rs +++ b/src/routes/client/update.rs @@ -15,6 +15,8 @@ pub async fn update_handler( pg_pool: web::Data, path: web::Path<(i32,)>, ) -> Result { + //todo owner + //todo admin endpoint let client_id = path.0; let mut client = db::client::fetch(pg_pool.get_ref(), client_id) .await From 046425cb5d3315bebbcc24634b43597ab972f8b4 Mon Sep 17 00:00:00 2001 From: petru Date: Wed, 28 Feb 2024 17:09:36 +0200 Subject: [PATCH 17/24] 30-access-policies --- src/routes/client/enable.rs | 5 +++-- src/startup.rs | 6 ++++++ tests/middleware_trydirect.rs | 4 ---- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/routes/client/enable.rs b/src/routes/client/enable.rs index ca36451c..c390a4ef 100644 --- a/src/routes/client/enable.rs +++ b/src/routes/client/enable.rs @@ -1,6 +1,6 @@ use crate::configuration::Settings; use crate::db; -use crate::helpers::client; +use crate::helpers; use crate::helpers::JsonResponse; use crate::models; use actix_web::{put, web, Responder, Result}; @@ -16,6 +16,7 @@ pub async fn enable_handler( pg_pool: web::Data, path: web::Path<(i32,)>, ) -> Result { + println!("user.id {}", user.id); //todo the owner //todo add admin endpoint let client_id = path.0; @@ -28,7 +29,7 @@ pub async fn enable_handler( return Err(JsonResponse::::build().bad_request("client is already active")); } - client.secret = client::generate_secret(pg_pool.get_ref(), 255) + client.secret = helpers::client::generate_secret(pg_pool.get_ref(), 255) .await .map(|secret| Some(secret)) .map_err(|err| JsonResponse::::build().bad_request(err))?; diff --git a/src/startup.rs b/src/startup.rs index 5e57dc85..5f0b30b8 100644 --- a/src/startup.rs +++ b/src/startup.rs @@ -41,6 +41,12 @@ pub async fn run( .service(routes::client::enable_handler) .service(routes::client::disable_handler), ) + /* + .service( + web::scope("/admin/client") + .service(routes::client::admin_enable_handler) + ) + */ .service( web::scope("/test").service(routes::test::deploy::handler), ) diff --git a/tests/middleware_trydirect.rs b/tests/middleware_trydirect.rs index 05906181..49377813 100644 --- a/tests/middleware_trydirect.rs +++ b/tests/middleware_trydirect.rs @@ -22,8 +22,4 @@ async fn middleware_trydirect_works() { assert!(response.status().is_success()); assert_eq!(Some(0), response.content_length()); - - - //todo header stacker-id not found - // } From 47eac8fcf274bf1cb973797177c8354e671fd402 Mon Sep 17 00:00:00 2001 From: petru Date: Fri, 1 Mar 2024 16:54:41 +0200 Subject: [PATCH 18/24] 30-access-policies admin enable client --- src/routes/client/enable.rs | 30 ++++++++++++++++++++++++++---- src/startup.rs | 2 -- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/routes/client/enable.rs b/src/routes/client/enable.rs index c390a4ef..79764110 100644 --- a/src/routes/client/enable.rs +++ b/src/routes/client/enable.rs @@ -8,7 +8,7 @@ use sqlx::PgPool; use std::sync::Arc; use tracing::Instrument; -#[tracing::instrument(name = "Enable client.")] +#[tracing::instrument(name = "User enable client.")] #[put("/{id}/enable")] pub async fn enable_handler( user: web::ReqData>, @@ -16,15 +16,37 @@ pub async fn enable_handler( pg_pool: web::Data, path: web::Path<(i32,)>, ) -> Result { - println!("user.id {}", user.id); - //todo the owner - //todo add admin endpoint let client_id = path.0; let mut client = db::client::fetch(pg_pool.get_ref(), client_id) .await .map_err(|msg| JsonResponse::::build().internal_server_error(msg))? .ok_or_else(|| JsonResponse::::build().not_found("not found"))?; + if client.user_id != user.id { + return Err(JsonResponse::::build().bad_request("client is not the owner")); + } + + enable_client(pg_pool, client).await +} + +#[tracing::instrument(name = "Admin enable client.")] +#[put("/{id}/enable")] +pub async fn admin_enable_handler( + user: web::ReqData>, + settings: web::Data, + pg_pool: web::Data, + path: web::Path<(i32,)>, +) -> Result { + let client_id = path.0; + let mut client = db::client::fetch(pg_pool.get_ref(), client_id) + .await + .map_err(|msg| JsonResponse::::build().internal_server_error(msg))? + .ok_or_else(|| JsonResponse::::build().not_found("not found"))?; + + enable_client(pg_pool, client).await +} + +async fn enable_client(pg_pool: web::Data, mut client: models::Client) -> Result { if client.secret.is_some() { return Err(JsonResponse::::build().bad_request("client is already active")); } diff --git a/src/startup.rs b/src/startup.rs index 5f0b30b8..7e3786dc 100644 --- a/src/startup.rs +++ b/src/startup.rs @@ -41,12 +41,10 @@ pub async fn run( .service(routes::client::enable_handler) .service(routes::client::disable_handler), ) - /* .service( web::scope("/admin/client") .service(routes::client::admin_enable_handler) ) - */ .service( web::scope("/test").service(routes::test::deploy::handler), ) From b9e6284ff791af65470eed20bcecf65ed8acfb20 Mon Sep 17 00:00:00 2001 From: petru Date: Sat, 2 Mar 2024 16:36:36 +0200 Subject: [PATCH 19/24] 30-access-policies client admin --- src/routes/client/disable.rs | 31 +++++++++++++++++++++++++++---- src/routes/client/enable.rs | 10 +++++----- src/routes/client/update.rs | 33 ++++++++++++++++++++++++++++----- src/startup.rs | 2 ++ 4 files changed, 62 insertions(+), 14 deletions(-) diff --git a/src/routes/client/disable.rs b/src/routes/client/disable.rs index 3c46fa65..892d3886 100644 --- a/src/routes/client/disable.rs +++ b/src/routes/client/disable.rs @@ -7,7 +7,7 @@ use sqlx::PgPool; use std::sync::Arc; use tracing::Instrument; -#[tracing::instrument(name = "Disable client.")] +#[tracing::instrument(name = "User disable client.")] #[put("/{id}/disable")] pub async fn disable_handler( user: web::ReqData>, @@ -15,20 +15,43 @@ pub async fn disable_handler( pg_pool: web::Data, path: web::Path<(i32,)>, ) -> Result { - //todo. the owner - //todo. add admin endpoint let client_id = path.0; let mut client = db::client::fetch(pg_pool.get_ref(), client_id) .await .map_err(|msg| JsonResponse::::build().internal_server_error(msg))? .ok_or_else(|| JsonResponse::::build().not_found("not found"))?; + if client.user_id != user.id { + return Err(JsonResponse::::build().bad_request("client is not the owner")); + } + + disable_client(pg_pool.get_ref(), client).await +} + +#[tracing::instrument(name = "Admin disable client.")] +#[put("/{id}/disable")] +pub async fn admin_disable_handler( + user: web::ReqData>, + settings: web::Data, + pg_pool: web::Data, + path: web::Path<(i32,)>, +) -> Result { + let client_id = path.0; + let mut client = db::client::fetch(pg_pool.get_ref(), client_id) + .await + .map_err(|msg| JsonResponse::::build().internal_server_error(msg))? + .ok_or_else(|| JsonResponse::::build().not_found("not found"))?; + + disable_client(pg_pool.get_ref(), client).await +} + +async fn disable_client(pg_pool: &PgPool, mut client: models::Client) -> Result { if client.secret.is_none() { return Err(JsonResponse::::build().bad_request("client is not active")); } client.secret = None; - db::client::update(pg_pool.get_ref(), client) + db::client::update(pg_pool, client) .await .map(|client| JsonResponse::build().set_item(client).ok("success")) .map_err(|msg| JsonResponse::::build().bad_request(msg)) diff --git a/src/routes/client/enable.rs b/src/routes/client/enable.rs index 79764110..5fb3c642 100644 --- a/src/routes/client/enable.rs +++ b/src/routes/client/enable.rs @@ -26,7 +26,7 @@ pub async fn enable_handler( return Err(JsonResponse::::build().bad_request("client is not the owner")); } - enable_client(pg_pool, client).await + enable_client(pg_pool.get_ref(), client).await } #[tracing::instrument(name = "Admin enable client.")] @@ -43,20 +43,20 @@ pub async fn admin_enable_handler( .map_err(|msg| JsonResponse::::build().internal_server_error(msg))? .ok_or_else(|| JsonResponse::::build().not_found("not found"))?; - enable_client(pg_pool, client).await + enable_client(pg_pool.get_ref(), client).await } -async fn enable_client(pg_pool: web::Data, mut client: models::Client) -> Result { +async fn enable_client(pg_pool: &PgPool, mut client: models::Client) -> Result { if client.secret.is_some() { return Err(JsonResponse::::build().bad_request("client is already active")); } - client.secret = helpers::client::generate_secret(pg_pool.get_ref(), 255) + client.secret = helpers::client::generate_secret(pg_pool, 255) .await .map(|secret| Some(secret)) .map_err(|err| JsonResponse::::build().bad_request(err))?; - db::client::update(pg_pool.get_ref(), client) + db::client::update(pg_pool, client) .await .map(|client| JsonResponse::build().set_item(client).ok("success")) .map_err(|err| JsonResponse::::build().bad_request(err)) diff --git a/src/routes/client/update.rs b/src/routes/client/update.rs index fe8db12e..506fd53f 100644 --- a/src/routes/client/update.rs +++ b/src/routes/client/update.rs @@ -7,7 +7,7 @@ use sqlx::PgPool; use std::sync::Arc; use tracing::Instrument; -#[tracing::instrument(name = "Update client.")] +#[tracing::instrument(name = "User update client.")] #[put("/{id}")] pub async fn update_handler( user: web::ReqData>, @@ -15,24 +15,47 @@ pub async fn update_handler( pg_pool: web::Data, path: web::Path<(i32,)>, ) -> Result { - //todo owner - //todo admin endpoint let client_id = path.0; let mut client = db::client::fetch(pg_pool.get_ref(), client_id) .await .map_err(|msg| JsonResponse::::build().internal_server_error(msg))? .ok_or_else(|| JsonResponse::::build().not_found("not found"))?; + if client.user_id != user.id { + return Err(JsonResponse::::build().bad_request("client is not the owner")); + } + + update_client(pg_pool.get_ref(), client).await +} + +#[tracing::instrument(name = "Admin update client.")] +#[put("/{id}")] +pub async fn admin_update_handler( + user: web::ReqData>, + settings: web::Data, + pg_pool: web::Data, + path: web::Path<(i32,)>, +) -> Result { + let client_id = path.0; + let mut client = db::client::fetch(pg_pool.get_ref(), client_id) + .await + .map_err(|msg| JsonResponse::::build().internal_server_error(msg))? + .ok_or_else(|| JsonResponse::::build().not_found("not found"))?; + + update_client(pg_pool.get_ref(), client).await +} + +async fn update_client(pg_pool: &PgPool, mut client: models::Client) -> Result { if client.secret.is_none() { return Err(JsonResponse::::build().bad_request("client is not active")); } - client.secret = client::generate_secret(pg_pool.get_ref(), 255) + client.secret = client::generate_secret(pg_pool, 255) .await .map(|s| Some(s)) .map_err(|msg| JsonResponse::::build().bad_request(msg))?; - db::client::update(pg_pool.get_ref(), client) + db::client::update(pg_pool, client) .await .map(|client| { JsonResponse::::build() diff --git a/src/startup.rs b/src/startup.rs index 7e3786dc..22d071f3 100644 --- a/src/startup.rs +++ b/src/startup.rs @@ -44,6 +44,8 @@ pub async fn run( .service( web::scope("/admin/client") .service(routes::client::admin_enable_handler) + .service(routes::client::admin_update_handler) + .service(routes::client::admin_disable_handler), ) .service( web::scope("/test").service(routes::test::deploy::handler), From de85d4b694ba6569a28fde0e818e615bcbe9b0ca Mon Sep 17 00:00:00 2001 From: petru Date: Sat, 2 Mar 2024 17:19:31 +0200 Subject: [PATCH 20/24] 30-access-policies removed src/routes/stack/service.rs --- src/routes/stack/service.rs | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/routes/stack/service.rs diff --git a/src/routes/stack/service.rs b/src/routes/stack/service.rs deleted file mode 100644 index e69de29b..00000000 From 618c30ea735c267a85d6173d63b203a1f02373ab Mon Sep 17 00:00:00 2001 From: petru Date: Sat, 2 Mar 2024 17:39:46 +0200 Subject: [PATCH 21/24] 30-access-policies owner logic for POST /stack/:id --- src/routes/stack/update.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/routes/stack/update.rs b/src/routes/stack/update.rs index ef11d825..72a0b441 100644 --- a/src/routes/stack/update.rs +++ b/src/routes/stack/update.rs @@ -27,11 +27,15 @@ pub async fn update( None => Err(JsonResponse::::build().not_found("Object not found")), })?; + if stack.user_id != user.id { + return Err(JsonResponse::::build().bad_request("client is not the owner")); + } + let stack_name = form.custom.custom_stack_code.clone(); tracing::debug!("form data: {:?}", form); let user_id = user.id.clone(); - if let Err(errors) = form.validate() { + if let Err(errors) = form.validate() { return Err(JsonResponse::::build().form_error(errors.to_string())); } From b599b98af9d5a7e5840239b270b3ff43846d4eb1 Mon Sep 17 00:00:00 2001 From: petru Date: Sat, 2 Mar 2024 17:59:49 +0200 Subject: [PATCH 22/24] 30-access-policies admin, GET /stack/:id --- src/routes/stack/get.rs | 19 +++++++++++++++++++ src/startup.rs | 4 ++++ 2 files changed, 23 insertions(+) diff --git a/src/routes/stack/get.rs b/src/routes/stack/get.rs index ccb9c9de..d6b2e27f 100644 --- a/src/routes/stack/get.rs +++ b/src/routes/stack/get.rs @@ -29,6 +29,25 @@ pub async fn item( }) } +#[tracing::instrument(name = "Get logged user stack.")] +#[get("/{id}")] +pub async fn admin_item( + user: web::ReqData>, + path: web::Path<(i32,)>, + pg_pool: web::Data, +) -> Result { + /// Get stack apps of logged user only + let (id,) = path.into_inner(); + + db::stack::fetch(pg_pool.get_ref(), id) + .await + .map_err(|err| JsonResponse::::build().internal_server_error(err)) + .and_then(|stack| match stack { + Some(stack) => Ok(JsonResponse::build().set_item(Some(stack)).ok("OK")), + None => Err(JsonResponse::::build().not_found("not found")), + }) +} + #[tracing::instrument(name = "Get user's stack list.")] #[get("/user/{id}")] pub async fn list( diff --git a/src/startup.rs b/src/startup.rs index 22d071f3..c59aff8e 100644 --- a/src/startup.rs +++ b/src/startup.rs @@ -69,6 +69,10 @@ pub async fn run( .service(routes::stack::add::add) .service(routes::stack::update::update), ) + .service( + web::scope("/admin/stack") + .service(routes::stack::get::admin_item) + ) .app_data(pg_pool.clone()) .app_data(mq_manager.clone()) .app_data(settings.clone()) From 15b890b61436ce190a41f1a52bab6ad88e74a990 Mon Sep 17 00:00:00 2001 From: petru Date: Sun, 3 Mar 2024 08:33:17 +0200 Subject: [PATCH 23/24] 30-access-policies GET /stack, GET /admin/stack/user/:id --- src/routes/stack/get.rs | 25 ++++++++++++++++++++----- src/startup.rs | 1 + 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/routes/stack/get.rs b/src/routes/stack/get.rs index d6b2e27f..132a6653 100644 --- a/src/routes/stack/get.rs +++ b/src/routes/stack/get.rs @@ -7,7 +7,22 @@ use std::convert::From; use std::sync::Arc; use tracing::Instrument; -#[tracing::instrument(name = "Get logged user stack.")] +#[tracing::instrument(name = "User get user's stack list.")] +#[get("")] +pub async fn list( + user: web::ReqData>, + pg_pool: web::Data, +) -> Result { + /// This is admin endpoint, used by a client app, client app is confidential + /// it should return stacks by user id + /// in order to pass validation at external deployment service + db::stack::fetch_by_user(pg_pool.get_ref(), &user.id) + .await + .map_err(|err| JsonResponse::::build().internal_server_error(err)) + .map(|stacks| JsonResponse::build().set_list(stacks).ok("OK")) +} + +#[tracing::instrument(name = "User get logged user stack.")] #[get("/{id}")] pub async fn item( user: web::ReqData>, @@ -29,7 +44,7 @@ pub async fn item( }) } -#[tracing::instrument(name = "Get logged user stack.")] +#[tracing::instrument(name = "Admin get logged user stack.")] #[get("/{id}")] pub async fn admin_item( user: web::ReqData>, @@ -48,10 +63,10 @@ pub async fn admin_item( }) } -#[tracing::instrument(name = "Get user's stack list.")] +#[tracing::instrument(name = "User get user's stack list.")] #[get("/user/{id}")] -pub async fn list( - user: web::ReqData>, +pub async fn admin_list( + admin: web::ReqData>, path: web::Path<(String,)>, pg_pool: web::Data, ) -> Result { diff --git a/src/startup.rs b/src/startup.rs index c59aff8e..b8052662 100644 --- a/src/startup.rs +++ b/src/startup.rs @@ -72,6 +72,7 @@ pub async fn run( .service( web::scope("/admin/stack") .service(routes::stack::get::admin_item) + .service(routes::stack::get::admin_list) ) .app_data(pg_pool.clone()) .app_data(mq_manager.clone()) From 98b5a7dda7a4247101dcb7072c6d34a1afe71fb3 Mon Sep 17 00:00:00 2001 From: petru Date: Mon, 4 Mar 2024 17:24:01 +0200 Subject: [PATCH 24/24] 30-access-policies /stack/:id/deploy --- src/routes/client/disable.rs | 14 ++++++++------ src/routes/stack/deploy.rs | 1 + src/routes/stack/update.rs | 5 +---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/routes/client/disable.rs b/src/routes/client/disable.rs index 892d3886..08a310cc 100644 --- a/src/routes/client/disable.rs +++ b/src/routes/client/disable.rs @@ -18,12 +18,14 @@ pub async fn disable_handler( let client_id = path.0; let mut client = db::client::fetch(pg_pool.get_ref(), client_id) .await - .map_err(|msg| JsonResponse::::build().internal_server_error(msg))? - .ok_or_else(|| JsonResponse::::build().not_found("not found"))?; - - if client.user_id != user.id { - return Err(JsonResponse::::build().bad_request("client is not the owner")); - } + .map_err(|msg| JsonResponse::::build().internal_server_error(msg)) + .and_then( |client| { + match client { + Some(client) if client.user_id != user.id => Err(JsonResponse::::build().bad_request("client is not the owner")), + Some(client) => Ok(client), + None => Err(JsonResponse::::build().not_found("not found")) + } + })?; disable_client(pg_pool.get_ref(), client).await } diff --git a/src/routes/stack/deploy.rs b/src/routes/stack/deploy.rs index a2bf8693..2120c16d 100644 --- a/src/routes/stack/deploy.rs +++ b/src/routes/stack/deploy.rs @@ -25,6 +25,7 @@ pub async fn add( .await .map_err(|err| JsonResponse::::build().internal_server_error(err)) .and_then(|stack| match stack { + Some(stack) if stack.user_id != user.id => Err(JsonResponse::::build().bad_request("client is not the owner")), Some(stack) => Ok(stack), None => Err(JsonResponse::::build().not_found("not found")), })?; diff --git a/src/routes/stack/update.rs b/src/routes/stack/update.rs index 72a0b441..c2eae717 100644 --- a/src/routes/stack/update.rs +++ b/src/routes/stack/update.rs @@ -23,14 +23,11 @@ pub async fn update( .await .map_err(|err| JsonResponse::::build().internal_server_error(err)) .and_then(|stack| match stack { + Some(stack) if stack.user_id != user.id => Err(JsonResponse::::build().bad_request("client is not the owner")), Some(stack) => Ok(stack), None => Err(JsonResponse::::build().not_found("Object not found")), })?; - if stack.user_id != user.id { - return Err(JsonResponse::::build().bad_request("client is not the owner")); - } - let stack_name = form.custom.custom_stack_code.clone(); tracing::debug!("form data: {:?}", form); let user_id = user.id.clone();