diff --git a/Cargo.lock b/Cargo.lock index 8a069ac..163882a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,35 +8,6 @@ version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" -[[package]] -name = "account_manager" -version = "0.1.0" -dependencies = [ - "bincode", - "bytes 1.6.0", - "channels", - "config", - "dotenv", - "fake", - "futures 0.3.30", - "gumdrop", - "json", - "kanidm_client", - "kanidm_proto", - "model", - "rauthy-client", - "rumqttc", - "serde", - "sqlx", - "sqlx-core 0.7.4", - "tarpc", - "testx", - "thiserror", - "tokio", - "tracing", - "uuid 1.9.0", -] - [[package]] name = "actix-codec" version = "0.5.2" @@ -401,7 +372,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd066d0b4ef8ecb03a55319dc13aa6910616d0f44008a045bb1835af830abff5" dependencies = [ "brotli", - "flate2", "futures-core", "memchr", "pin-project-lite", @@ -756,12 +726,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" -[[package]] -name = "base32" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23ce669cd6c8588f79e15cf450314f9638f967fc5770ff1c7c1deb0925ea7cfa" - [[package]] name = "base64" version = "0.13.1" @@ -786,17 +750,6 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" -[[package]] -name = "base64urlsafedata" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a56894edf5cd1efa7068d7454adeb7ce0b3da4ffa5ab08cfc06165bbc62f0c7" -dependencies = [ - "base64 0.21.7", - "paste", - "serde", -] - [[package]] name = "bigdecimal" version = "0.3.1" @@ -912,7 +865,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3ef8005764f53cd4dca619f5bf64cafd4664dada50ece25e4d81de54c80cc0b" dependencies = [ "once_cell", - "proc-macro-crate 3.1.0", + "proc-macro-crate", "proc-macro2", "quote", "syn 2.0.68", @@ -1262,22 +1215,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3f6d59c71e7dc3af60f0af9db32364d96a16e9310f3f5db2b55ed642162dd35" -[[package]] -name = "compact_jwt" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1aca09e6a9e9011c2a2fb13f26a0d2440a709ac0e68ccf02d168d54f4801b27" -dependencies = [ - "base64 0.21.7", - "base64urlsafedata", - "hex", - "serde", - "serde_json", - "tracing", - "url", - "uuid 1.9.0", -] - [[package]] name = "concurrent-queue" version = "2.5.0" @@ -1344,17 +1281,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "cookie" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7efb37c3e1ccb1ff97164ad95ac1606e8ccd35b3fa0a7d99a304c7f4a428cc24" -dependencies = [ - "percent-encoding", - "time", - "version_check", -] - [[package]] name = "cookie" version = "0.18.1" @@ -1370,23 +1296,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "cookie_store" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "387461abbc748185c3a6e1673d826918b450b87ff22639429c694619a83b6cf6" -dependencies = [ - "cookie 0.17.0", - "idna 0.3.0", - "log", - "publicsuffix", - "serde", - "serde_derive", - "serde_json", - "time", - "url", -] - [[package]] name = "core-foundation" version = "0.9.4" @@ -2703,16 +2612,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" -[[package]] -name = "idna" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - [[package]] name = "idna" version = "0.5.0" @@ -2723,6 +2622,33 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "idp" +version = "0.1.0" +dependencies = [ + "bincode", + "bytes 1.6.0", + "channels", + "config", + "dotenv", + "fake", + "futures 0.1.31", + "gumdrop", + "json", + "model", + "rauthy-client", + "rumqttc", + "serde", + "sqlx", + "sqlx-core 0.6.3", + "tarpc", + "testx", + "thiserror", + "tokio", + "tracing", + "uuid 1.9.0", +] + [[package]] name = "image" version = "0.25.1" @@ -2742,7 +2668,6 @@ checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown 0.12.3", - "serde", ] [[package]] @@ -2753,7 +2678,6 @@ checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", "hashbrown 0.14.5", - "serde", ] [[package]] @@ -2927,69 +2851,6 @@ dependencies = [ "signature", ] -[[package]] -name = "kanidm_client" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "096cddae6b5b1891c58ecf3056f45205be68f995e21278e006d32fed71910e7d" -dependencies = [ - "compact_jwt", - "hyper 0.14.29", - "kanidm_lib_file_permissions", - "kanidm_proto", - "reqwest 0.11.27", - "serde", - "serde_json", - "time", - "tokio", - "toml 0.5.11", - "tracing", - "url", - "uuid 1.9.0", - "webauthn-rs-proto", -] - -[[package]] -name = "kanidm_lib_file_permissions" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1bb7525ce9007b0798a8eaf010708ef49da7f1b2516eebd3058f253df6db843" -dependencies = [ - "kanidm_utils_users", - "whoami", -] - -[[package]] -name = "kanidm_proto" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad03a5e96bf8a4fa981b864c3317950dce7d7ea6b0e8accd61329ec72ca1cd6" -dependencies = [ - "base32", - "base64urlsafedata", - "num_enum", - "scim_proto", - "serde", - "serde_json", - "serde_with", - "time", - "tracing", - "url", - "urlencoding", - "utoipa", - "uuid 1.9.0", - "webauthn-rs-proto", -] - -[[package]] -name = "kanidm_utils_users" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89aa036a35fe4b2953c7c8ab8ad456db3ab8547aec1f1a762ab524d7480c243b" -dependencies = [ - "libc", -] - [[package]] name = "kv-log-macro" version = "1.0.7" @@ -3211,16 +3072,6 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" -[[package]] -name = "mime_guess" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" -dependencies = [ - "mime", - "unicase", -] - [[package]] name = "minidom" version = "0.15.2" @@ -3401,36 +3252,6 @@ dependencies = [ "libc", ] -[[package]] -name = "num_enum" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" -dependencies = [ - "num_enum_derive", -] - -[[package]] -name = "num_enum_derive" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" -dependencies = [ - "proc-macro-crate 1.3.1", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "num_threads" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" -dependencies = [ - "libc", -] - [[package]] name = "object" version = "0.36.0" @@ -3834,33 +3655,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "peg" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a625d12ad770914cbf7eff6f9314c3ef803bfe364a1b20bc36ddf56673e71e5" -dependencies = [ - "peg-macros", - "peg-runtime", -] - -[[package]] -name = "peg-macros" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f241d42067ed3ab6a4fece1db720838e1418f36d868585a27931f95d6bc03582" -dependencies = [ - "peg-runtime", - "proc-macro2", - "quote", -] - -[[package]] -name = "peg-runtime" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3aeb8f54c078314c2065ee649a7241f46b9d8e418e1a9581ba0546657d7aa3a" - [[package]] name = "pem-rfc7468" version = "0.7.0" @@ -4028,16 +3822,6 @@ dependencies = [ "elliptic-curve", ] -[[package]] -name = "proc-macro-crate" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" -dependencies = [ - "once_cell", - "toml_edit 0.19.15", -] - [[package]] name = "proc-macro-crate" version = "3.1.0" @@ -4103,12 +3887,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "psl-types" -version = "2.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac" - [[package]] name = "ptr_meta" version = "0.1.4" @@ -4129,16 +3907,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "publicsuffix" -version = "2.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96a8c1bda5ae1af7f99a2962e49df150414a43d62404644d98dd5c3a93d07457" -dependencies = [ - "idna 0.3.0", - "psl-types", -] - [[package]] name = "qrcode" version = "0.14.0" @@ -4513,11 +4281,8 @@ version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ - "async-compression", "base64 0.21.7", "bytes 1.6.0", - "cookie 0.17.0", - "cookie_store", "encoding_rs", "futures-core", "futures-util", @@ -4530,7 +4295,6 @@ dependencies = [ "js-sys", "log", "mime", - "mime_guess", "native-tls", "once_cell", "percent-encoding", @@ -4956,23 +4720,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "scim_proto" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55fbcfbcbc11ff46228a2b7b6018e1f6f37499fff47851e20583862ba1d9ef3f" -dependencies = [ - "base64 0.22.1", - "peg", - "serde", - "serde_json", - "time", - "tracing", - "tracing-subscriber", - "url", - "uuid 1.9.0", -] - [[package]] name = "scopeguard" version = "1.2.0" @@ -5192,17 +4939,6 @@ dependencies = [ "serde_derive", ] -[[package]] -name = "serde-wasm-bindgen" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" -dependencies = [ - "js-sys", - "serde", - "wasm-bindgen", -] - [[package]] name = "serde_derive" version = "1.0.203" @@ -5278,36 +5014,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_with" -version = "3.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad483d2ab0149d5a5ebcd9972a3852711e0153d863bf5a5d0391d28883c4a20" -dependencies = [ - "base64 0.22.1", - "chrono", - "hex", - "indexmap 1.9.3", - "indexmap 2.2.6", - "serde", - "serde_derive", - "serde_json", - "serde_with_macros", - "time", -] - -[[package]] -name = "serde_with_macros" -version = "3.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65569b702f41443e8bc8bbb1c5779bd0450bbe723b56198980e80ec45780bce2" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn 2.0.68", -] - [[package]] name = "sha1" version = "0.10.6" @@ -5879,9 +5585,7 @@ checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", - "libc", "num-conv", - "num_threads", "powerfmt", "serde", "time-core", @@ -6054,15 +5758,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "toml" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" -dependencies = [ - "serde", -] - [[package]] name = "toml" version = "0.7.8" @@ -6376,15 +6071,6 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" -[[package]] -name = "unicase" -version = "2.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" -dependencies = [ - "version_check", -] - [[package]] name = "unicode-bidi" version = "0.3.15" @@ -6453,7 +6139,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", - "idna 0.5.0", + "idna", "percent-encoding", "serde", ] @@ -6473,30 +6159,6 @@ version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" -[[package]] -name = "utoipa" -version = "4.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5afb1a60e207dca502682537fefcfd9921e71d0b83e9576060f09abc6efab23" -dependencies = [ - "indexmap 2.2.6", - "serde", - "serde_json", - "utoipa-gen", -] - -[[package]] -name = "utoipa-gen" -version = "4.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bf0e16c02bc4bf5322ab65f10ab1149bdbcaa782cba66dc7057370a3f8190be" -dependencies = [ - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.68", -] - [[package]] name = "uuid" version = "0.8.2" @@ -6525,7 +6187,7 @@ version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db79c75af171630a3148bd3e6d7c4f42b6a9a014c2945bc5ed0020cbb8d9478e" dependencies = [ - "idna 0.5.0", + "idna", "once_cell", "regex", "serde", @@ -6613,8 +6275,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", - "serde", - "serde_json", "wasm-bindgen-macro", ] @@ -6697,23 +6357,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "webauthn-rs-proto" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f1c6dc254607f48eec3bdb35b86b377202436859ca1e4c9290afafd7349dcc3" -dependencies = [ - "base64 0.21.7", - "base64urlsafedata", - "js-sys", - "serde", - "serde-wasm-bindgen", - "serde_json", - "url", - "wasm-bindgen", - "web-sys", -] - [[package]] name = "webpki" version = "0.22.4" diff --git a/Cargo.toml b/Cargo.toml index e0cc4a3..06b0d28 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ members = [ "crates/testx", "crates/db-utils", # actors - "crates/account_manager", + "crates/idp", # "crates/cart_manager", # "crates/database_manager", # "crates/email_manager", diff --git a/crates/account_manager/Cargo.toml b/crates/account_manager/Cargo.toml deleted file mode 100644 index dbd48ef..0000000 --- a/crates/account_manager/Cargo.toml +++ /dev/null @@ -1,35 +0,0 @@ -[package] -name = "account_manager" -version = "0.1.0" -edition = "2021" - -[[bin]] -name = "account-manager" -path = "src/main.rs" - -[dependencies] -bincode = { version = "1" } -bytes = { version = "1" } -channels = { path = "../channels" } -config = { path = "../config" } -dotenv = { version = "0" } -futures = { version = "0" } -gumdrop = { version = "0" } -json = { version = "0" } -kanidm_client = "1.2.2" -kanidm_proto = "1.2.2" -model = { path = "../model", features = ['db'] } -rauthy-client = { version = "0.4.0", features = ["actix-web", "qrcode"] } -rumqttc = { version = "*" } -serde = { version = "1", features = ["derive"] } -sqlx = { version = "0", features = ["migrate", "runtime-actix-rustls", "all-types", "postgres"] } -sqlx-core = { version = "0", features = [] } -tarpc = { version = "0", features = ["tokio1", "serde-transport-bincode", "serde-transport", "serde", "serde-transport-json", "tcp"] } -thiserror = { version = "1" } -tokio = { version = "1", features = ['full'] } -tracing = { version = "0" } -uuid = { workspace = true, features = ["v4"] } - -[dev-dependencies] -fake = { version = "2" } -testx = { path = "../testx" } diff --git a/crates/account_manager/migrations/202204131841_init.sql b/crates/account_manager/migrations/202204131841_init.sql deleted file mode 100644 index 8e54c83..0000000 --- a/crates/account_manager/migrations/202204131841_init.sql +++ /dev/null @@ -1,23 +0,0 @@ -CREATE EXTENSION IF NOT EXISTS "uuid-ossp" WITH SCHEMA public; - -CREATE TYPE "AccountState" AS ENUM ( - 'active', - 'suspended', - 'banned' - ); - -CREATE TYPE "Role" AS ENUM ( - 'admin', - 'user' - ); - -CREATE TABLE public.accounts -( - id serial NOT NULL, - email character varying NOT NULL, - login character varying NOT NULL, - pass_hash character varying NOT NULL, - role "Role" DEFAULT 'user'::"Role" NOT NULL, - customer_id uuid DEFAULT gen_random_uuid() NOT NULL, - state "AccountState" DEFAULT 'active'::"AccountState" NOT NULL -); diff --git a/crates/account_manager/migrations/202204131842_addresses.sql b/crates/account_manager/migrations/202204131842_addresses.sql deleted file mode 100644 index ea595c9..0000000 --- a/crates/account_manager/migrations/202204131842_addresses.sql +++ /dev/null @@ -1,13 +0,0 @@ -CREATE TABLE public.account_addresses -( - id serial NOT NULL, - name text NOT NULL, - email text NOT NULL, - street text NOT NULL, - city text NOT NULL, - country text NOT NULL, - zip text NOT NULL, - account_id integer, - is_default boolean DEFAULT false NOT NULL, - phone text DEFAULT ''::text NOT NULL -); diff --git a/crates/account_manager/src/actions.rs b/crates/account_manager/src/actions.rs deleted file mode 100644 index 61026e0..0000000 --- a/crates/account_manager/src/actions.rs +++ /dev/null @@ -1,124 +0,0 @@ -use channels::accounts::{all, find_by_identity, me, register}; -use config::SharedAppConfig; -use model::{Encrypt, FullAccount, Ranged}; - -use crate::db::{AccountAddresses, Database, FindAccount}; -use crate::{Error, Result}; - -macro_rules! ok_or_rollback { - ($res: expr, $t: expr, $err: expr) => { - match $res { - Ok(v) => v, - Err(e) => { - tracing::error!("{}", e); - $t.rollback().await.ok(); - - return Err($err); - } - } - }; -} - -macro_rules! begin_t { - ($db: expr, $err: expr) => { - match $db.pool.begin().await { - Ok(t) => t, - Err(e) => { - tracing::error!("{}", e); - return Err($err); - } - } - }; -} - -pub async fn all(input: all::Input, db: Database) -> all::Output { - use channels::accounts::Error; - - let mut t = begin_t!(db, Error::DbCritical); - - let dbm = crate::db::AllAccounts { - limit: input.limit.into_raw(), - offset: input.offset.into_raw(), - }; - - let res = dbm.run(&mut t).await; - - let accounts = ok_or_rollback!(res, t, Error::All); - - t.commit().await.map_err(|e| { - tracing::error!("{}", e); - Error::DbCritical - })?; - - Ok(all::Details { accounts }) -} - -pub async fn me(account_id: model::AccountId, db: Database) -> me::Output { - use channels::accounts::Error; - - let mut t = begin_t!(db, Error::Account); - - let res = FindAccount { account_id }.run(&mut t).await; - let account: FullAccount = ok_or_rollback!(res, t, Error::Account); - - let res = AccountAddresses { account_id }.run(&mut t).await; - let addresses = ok_or_rollback!(res, t, Error::Addresses); - - t.commit().await.map_err(|e| { - tracing::error!("{}", e); - Error::DbCritical - })?; - - Ok(me::Details { account, addresses }) -} - -pub async fn create_account( - msg: register::Input, - db: &Database, - config: SharedAppConfig, -) -> Result { - let salt = config.lock().web().pass_salt(); - let hash = msg.password.encrypt(&salt).map_err(|e| { - tracing::error!("{e:?}"); - Error::Hashing - })?; - - let mut t = begin_t!(db, Error::DbCritical); - - let res = crate::db::CreateAccount { - email: msg.email, - login: msg.login, - pass_hash: model::PassHash::new(hash), - role: msg.role, - } - .run(&mut t) - .await; - - let account: FullAccount = ok_or_rollback!(res, t, Error::Saving); - - t.commit().await.map_err(|e| { - tracing::error!("{}", e); - Error::DbCritical - })?; - - Ok(account) -} - -pub async fn find_by_identity( - input: find_by_identity::Input, - db: Database, -) -> find_by_identity::Output { - use channels::accounts::Error; - - let mut t = begin_t!(db, Error::DbCritical); - let dbm = crate::db::AccountByIdentity { - login: input.login, - email: input.email, - }; - - let res = dbm.run(&mut t).await; - - let account: FullAccount = ok_or_rollback!(res, t, Error::InvalidIdentity); - - Ok(find_by_identity::Details { account }) -} diff --git a/crates/account_manager/src/bin/account-client.rs b/crates/account_manager/src/bin/account-client.rs deleted file mode 100644 index 264421f..0000000 --- a/crates/account_manager/src/bin/account-client.rs +++ /dev/null @@ -1,39 +0,0 @@ -use std::time::Duration; - -use config::UpdateConfig; -use tarpc::context; -use tokio::time::sleep; - -#[derive(gumdrop::Options)] -struct Flags { - help: bool, - /// Sets the name to say hello to. - name: String, -} - -impl UpdateConfig for Flags {} - -#[tokio::main] -async fn main() -> std::io::Result<()> { - use channels::accounts::me::Input; - - let opts: Flags = gumdrop::Options::parse_args_default_or_exit(); - - let config = config::default_load(&opts); - let client = channels::accounts::rpc::create_client(config).await; - - let r = client - .me( - context::current(), - Input { - account_id: 1.into(), - }, - ) - .await; - println!("{:?}", r); - - // Let the background span processor finish. - sleep(Duration::from_micros(1)).await; - - Ok(()) -} diff --git a/crates/account_manager/src/db/accounts.rs b/crates/account_manager/src/db/accounts.rs deleted file mode 100644 index 6b098b6..0000000 --- a/crates/account_manager/src/db/accounts.rs +++ /dev/null @@ -1,441 +0,0 @@ -use model::{AccountId, AccountState, Email, FullAccount, Login, PassHash, Role}; - -pub type Result = std::result::Result; - -#[derive(Debug, Copy, Clone, PartialEq, Eq, thiserror::Error)] -pub enum Error { - #[error("Can't create account")] - CantCreate, - #[error("Can't find account does to lack of identity")] - NoIdentity, - #[error("Account does not exists")] - NotExists, - #[error("Failed to load all accounts")] - All, - #[error("Can't update account")] - CantUpdate, -} - -#[derive(Debug)] -pub struct AllAccounts { - pub limit: i32, - pub offset: i32, -} - -impl AllAccounts { - pub async fn run( - self, - pool: &mut sqlx::Transaction<'_, sqlx::Postgres>, - ) -> Result> { - sqlx::query_as( - r#" -SELECT id, email, login, pass_hash, role, customer_id, state -FROM accounts -LIMIT $1 OFFSET $2 - "#, - ) - .bind(self.limit) - .bind(self.offset) - .fetch_all(pool) - .await - .map_err(|e| { - tracing::error!("{e:?}"); - Error::All - }) - } -} - -#[derive(Debug)] -pub struct CreateAccount { - pub email: Email, - pub login: Login, - pub pass_hash: PassHash, - pub role: Role, -} - -impl CreateAccount { - pub async fn run( - self, - pool: &mut sqlx::Transaction<'_, sqlx::Postgres>, - ) -> Result { - sqlx::query_as( - r#" -INSERT INTO accounts (login, email, role, pass_hash) -VALUES ($1, $2, $3, $4) -RETURNING id, email, login, pass_hash, role, customer_id, state - "#, - ) - .bind(self.login) - .bind(self.email) - .bind(self.role) - .bind(self.pass_hash) - .fetch_one(pool) - .await - .map_err(|e| { - tracing::error!("{e:?}"); - Error::CantCreate - }) - } -} - -#[derive(Debug)] -pub struct UpdateAccount { - pub id: AccountId, - pub email: Email, - pub login: Login, - pub pass_hash: Option, - pub role: Role, - pub state: AccountState, -} - -impl UpdateAccount { - pub async fn run( - self, - pool: &mut sqlx::Transaction<'_, sqlx::Postgres>, - ) -> Result { - match self.pass_hash { - Some(hash) => sqlx::query_as( - r#" -UPDATE accounts -SET login = $2, email = $3, role = $4, pass_hash = $5, state = $6 -WHERE id = $1 -RETURNING id, email, login, pass_hash, role, customer_id, state - "#, - ) - .bind(self.id) - .bind(self.login) - .bind(self.email) - .bind(self.role) - .bind(hash) - .bind(self.state), - None => sqlx::query_as( - r#" -UPDATE accounts -SET login = $2, email = $3, role = $4, state = $5 -WHERE id = $1 -RETURNING id, email, login, pass_hash, role, customer_id, state - "#, - ) - .bind(self.id) - .bind(self.login) - .bind(self.email) - .bind(self.role) - .bind(self.state), - } - .fetch_one(pool) - .await - .map_err(|e| { - tracing::error!("{e:?}"); - Error::CantUpdate - }) - } -} - -#[derive(Debug)] -pub struct FindAccount { - pub account_id: AccountId, -} - -impl FindAccount { - pub async fn run( - self, - pool: &mut sqlx::Transaction<'_, sqlx::Postgres>, - ) -> Result { - sqlx::query_as( - r#" -SELECT id, email, login, pass_hash, role, customer_id, state -FROM accounts -WHERE id = $1 - "#, - ) - .bind(self.account_id) - .fetch_one(pool) - .await - .map_err(|e| { - tracing::error!("{e:?}"); - Error::NotExists - }) - } -} - -#[derive(Debug)] -pub struct AccountByIdentity { - pub login: Option, - pub email: Option, -} - -impl AccountByIdentity { - pub async fn run( - self, - pool: &mut sqlx::Transaction<'_, sqlx::Postgres>, - ) -> Result { - match (self.login, self.email) { - (Some(login), None) => sqlx::query_as( - r#" -SELECT id, email, login, pass_hash, role, customer_id, state -FROM accounts -WHERE login = $1 - "#, - ) - .bind(login), - (None, Some(email)) => sqlx::query_as( - r#" -SELECT id, email, login, pass_hash, role, customer_id, state -FROM accounts -WHERE email = $1 - "#, - ) - .bind(email), - (Some(login), Some(email)) => sqlx::query_as( - r#" -SELECT id, email, login, pass_hash, role, customer_id, state -FROM accounts -WHERE login = $1 AND email = $2 - "#, - ) - .bind(login) - .bind(email), - _ => return Err(Error::NoIdentity), - } - .fetch_one(pool) - .await - .map_err(|e| { - tracing::error!("{e:?}"); - Error::CantCreate - }) - } -} - -#[cfg(test)] -mod tests { - use config::UpdateConfig; - use fake::Fake; - use model::*; - - use super::*; - use crate::db::Database; - - pub struct NoOpts; - - impl UpdateConfig for NoOpts {} - - async fn test_create_account( - t: &mut sqlx::Transaction<'_, sqlx::Postgres>, - login: Option, - email: Option, - hash: Option, - ) -> FullAccount { - use fake::faker::internet::en; - let login: String = login.unwrap_or_else(|| en::Username().fake()); - let email: String = email.unwrap_or_else(|| en::FreeEmail().fake()); - let hash: String = hash.unwrap_or_else(|| en::Password(10..20).fake()); - - CreateAccount { - email: Email::new(email), - login: Login::new(login), - pass_hash: PassHash::new(hash), - role: Role::Admin, - } - .run(t) - .await - .unwrap() - } - - #[tokio::test] - async fn create_account() { - testx::db_t_ref!(t); - - let login: String = fake::faker::internet::en::Username().fake(); - let email: String = fake::faker::internet::en::FreeEmail().fake(); - let hash: String = fake::faker::internet::en::Password(10..20).fake(); - - let account: FullAccount = CreateAccount { - email: Email::new(&email), - login: Login::new(&login), - pass_hash: PassHash::new(&hash), - role: Role::Admin, - } - .run(&mut t) - .await - .unwrap(); - - let expected = FullAccount { - login: Login::new(login), - email: Email::new(email), - pass_hash: PassHash::new(&hash), - role: Role::Admin, - customer_id: account.customer_id, - id: account.id, - state: AccountState::Active, - }; - - t.rollback().await.unwrap(); - assert_eq!(account, expected); - } - - #[tokio::test] - async fn all_accounts() { - testx::db_t_ref!(t); - - test_create_account(&mut t, None, None, None).await; - test_create_account(&mut t, None, None, None).await; - test_create_account(&mut t, None, None, None).await; - - let v: Vec = AllAccounts { - limit: 200, - offset: 0, - } - .run(&mut t) - .await - .unwrap(); - - testx::db_rollback!(t); - assert!(v.len() >= 3); - } - - #[tokio::test] - async fn update_account_without_pass() { - testx::db_t_ref!(t); - - let original_login: String = fake::faker::internet::en::Username().fake(); - let original_email: String = fake::faker::internet::en::FreeEmail().fake(); - let original_hash: String = fake::faker::internet::en::Password(10..20).fake(); - - let original_account = test_create_account( - &mut t, - Some(original_login.clone()), - Some(original_email.clone()), - Some(original_hash.clone()), - ) - .await; - - let updated_login: String = fake::faker::internet::en::Username().fake(); - let updated_email: String = fake::faker::internet::en::FreeEmail().fake(); - - let updated_account: FullAccount = UpdateAccount { - id: original_account.id, - email: Email::new(updated_email.clone()), - login: Login::new(updated_login.clone()), - pass_hash: None, - role: Role::Admin, - state: AccountState::Active, - } - .run(&mut t) - .await - .unwrap(); - - let expected = FullAccount { - id: original_account.id, - email: Email::new(updated_email), - login: Login::new(updated_login), - pass_hash: PassHash::new(original_hash), - role: Role::Admin, - customer_id: original_account.customer_id, - state: AccountState::Active, - }; - - testx::db_rollback!(t); - assert_ne!(original_account, expected); - assert_eq!(updated_account, expected); - } - - #[tokio::test] - async fn update_account_with_pass() { - testx::db_t_ref!(t); - - let original_login: String = fake::faker::internet::en::Username().fake(); - let original_email: String = fake::faker::internet::en::FreeEmail().fake(); - let original_hash: String = fake::faker::internet::en::Password(10..20).fake(); - - let original_account = test_create_account( - &mut t, - Some(original_login.clone()), - Some(original_email.clone()), - Some(original_hash.clone()), - ) - .await; - - let updated_login: String = fake::faker::internet::en::Username().fake(); - let updated_email: String = fake::faker::internet::en::FreeEmail().fake(); - let updated_hash: String = fake::faker::internet::en::Password(10..20).fake(); - - let updated_account: FullAccount = UpdateAccount { - id: original_account.id, - email: Email::new(updated_email.clone()), - login: Login::new(updated_login.clone()), - pass_hash: Some(PassHash::new(updated_hash.clone())), - role: Role::Admin, - state: AccountState::Active, - } - .run(&mut t) - .await - .unwrap(); - - let expected = FullAccount { - id: original_account.id, - email: Email::new(updated_email), - login: Login::new(updated_login), - pass_hash: PassHash::new(updated_hash), - role: Role::Admin, - customer_id: original_account.customer_id, - state: AccountState::Active, - }; - - testx::db_rollback!(t); - assert_ne!(original_account, expected); - assert_eq!(updated_account, expected); - } - - #[tokio::test] - async fn find() { - testx::db_t_ref!(t); - - let account = test_create_account(&mut t, None, None, None).await; - - let res: FullAccount = FindAccount { - account_id: account.id, - } - .run(&mut t) - .await - .unwrap(); - - testx::db_rollback!(t); - assert_eq!(account, res); - } - - #[tokio::test] - async fn find_identity_email() { - testx::db_t_ref!(t); - - let account = test_create_account(&mut t, None, None, None).await; - - let res: FullAccount = AccountByIdentity { - email: Some(account.email.clone()), - login: None, - } - .run(&mut t) - .await - .unwrap(); - - testx::db_rollback!(t); - assert_eq!(account, res); - } - - #[tokio::test] - async fn find_identity_login() { - testx::db_t_ref!(t); - - let account = test_create_account(&mut t, None, None, None).await; - - let res: FullAccount = AccountByIdentity { - login: Some(account.login.clone()), - email: None, - } - .run(&mut t) - .await - .unwrap(); - - testx::db_rollback!(t); - assert_eq!(account, res); - } -} diff --git a/crates/account_manager/src/db/addresses.rs b/crates/account_manager/src/db/addresses.rs deleted file mode 100644 index 7d8aab8..0000000 --- a/crates/account_manager/src/db/addresses.rs +++ /dev/null @@ -1,311 +0,0 @@ -pub type Result = std::result::Result; - -#[derive(Debug, Copy, Clone, PartialEq, Eq, serde::Serialize, thiserror::Error)] -pub enum Error { - #[error("Can't load account addresses")] - AccountAddresses, - #[error("Failed to save account address")] - CreateAccountAddress, -} - -#[derive(Debug)] -pub struct AccountAddresses { - pub account_id: model::AccountId, -} - -impl AccountAddresses { - pub async fn run( - self, - pool: &mut sqlx::Transaction<'_, sqlx::Postgres>, - ) -> Result> { - sqlx::query_as( - r#" -SELECT id, name, email, phone, street, city, country, zip, account_id, is_default -FROM account_addresses -WHERE account_id = $1 - "#, - ) - .bind(self.account_id) - .fetch_all(pool) - .await - .map_err(|_| Error::AccountAddresses.into()) - } -} - -#[derive(Debug)] -pub struct FindAccountAddress { - pub account_id: model::AccountId, - pub address_id: model::AddressId, -} - -impl FindAccountAddress { - pub async fn run( - self, - pool: &mut sqlx::Transaction<'_, sqlx::Postgres>, - ) -> Result { - sqlx::query_as( - r#" -SELECT id, name, email, phone, street, city, country, zip, account_id, is_default -FROM account_addresses -WHERE account_id = $1 AND id = $2 - "#, - ) - .bind(self.account_id) - .bind(self.address_id) - .fetch_one(pool) - .await - .map_err(|_| Error::AccountAddresses.into()) - } -} - -#[derive(Debug)] -pub struct DefaultAccountAddress { - pub account_id: model::AccountId, -} - -impl DefaultAccountAddress { - pub async fn run( - self, - pool: &mut sqlx::Transaction<'_, sqlx::Postgres>, - ) -> Result { - sqlx::query_as( - r#" -SELECT id, name, email, phone, street, city, country, zip, account_id, is_default -FROM account_addresses -WHERE account_id = $1 AND is_default - "#, - ) - .bind(self.account_id) - .fetch_one(pool) - .await - .map_err(|_| Error::AccountAddresses.into()) - } -} - -#[derive(Debug)] -pub struct CreateAccountAddress { - pub name: model::Name, - pub email: model::Email, - pub phone: model::Phone, - pub street: model::Street, - pub city: model::City, - pub country: model::Country, - pub zip: model::Zip, - pub account_id: Option, - pub is_default: bool, -} - -impl CreateAccountAddress { - pub async fn run( - self, - pool: &mut sqlx::Transaction<'_, sqlx::Postgres>, - ) -> Result { - if self.is_default && self.account_id.is_some() { - if let Err(e) = sqlx::query( - r#" -UPDATE account_addresses -SET is_default = FALSE -WHERE account_id = $1 - "#, - ) - .bind(self.account_id) - .fetch_all(&mut *pool) - .await - { - tracing::error!("{e}"); - dbg!(e); - } - } - - sqlx::query_as( - r#" -INSERT INTO account_addresses ( name, email, phone, street, city, country, zip, account_id, is_default) -VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) -RETURNING id, name, email, phone, street, city, country, zip, account_id, is_default - "#, - ) - .bind(self.name) - .bind(self.email) - .bind(self.phone) - .bind(self.street) - .bind(self.city) - .bind(self.country) - .bind(self.zip) - .bind(self.account_id) - .bind(self.is_default) - .fetch_one(pool) - .await - .map_err(|e| { - tracing::error!("{e}"); - dbg!(e); - Error::CreateAccountAddress.into() - }) - } -} - -#[derive(Debug)] -pub struct UpdateAccountAddress { - pub id: model::AddressId, - pub name: model::Name, - pub email: model::Email, - pub phone: model::Phone, - pub street: model::Street, - pub city: model::City, - pub country: model::Country, - pub zip: model::Zip, - pub account_id: model::AccountId, - pub is_default: bool, -} - -impl UpdateAccountAddress { - pub async fn run( - self, - pool: &mut sqlx::Transaction<'_, sqlx::Postgres>, - ) -> Result { - sqlx::query_as( - r#" -UPDATE account_addresses -SET name = $2, email = $3, street = $4, city = $5, country = $6, zip = $7, account_id = $8, is_default = $9, phone = $10 -WHERE id = $1 -RETURNING id, name, email, phone, street, city, country, zip, account_id, is_default - "#, - ) - .bind(self.id) - .bind(self.name) - .bind(self.email) - .bind(self.street) - .bind(self.city) - .bind(self.country) - .bind(self.zip) - .bind(self.account_id) - .bind(self.is_default) - .bind(self.phone) - .fetch_one(pool) - .await - .map_err(|_| Error::CreateAccountAddress.into()) - } -} - -#[cfg(test)] -mod test { - use config::*; - use fake::Fake; - use model::*; - - use super::super::accounts::CreateAccount; - use super::*; - use crate::db::Database; - - pub struct NoOpts; - - impl UpdateConfig for NoOpts {} - - async fn test_create_account(pool: &mut sqlx::Transaction<'_, sqlx::Postgres>) -> FullAccount { - let login: String = fake::faker::internet::en::Username().fake(); - let email: String = fake::faker::internet::en::FreeEmail().fake(); - let hash: String = fake::faker::internet::en::Password(10..20).fake(); - - CreateAccount { - email: Email::new(email), - login: Login::new(login), - pass_hash: PassHash::new(hash), - role: Role::Admin, - } - .run(pool) - .await - .unwrap() - } - - #[tokio::test] - async fn full_check() { - testx::db_t_ref!(t); - - // account - let account = test_create_account(&mut t).await; - - // address - let mut address: AccountAddress = { - let name: String = fake::faker::name::en::Name().fake(); - let email: String = fake::faker::internet::en::FreeEmail().fake(); - let phone: String = fake::faker::phone_number::en::PhoneNumber().fake(); - let street: String = fake::faker::address::en::StreetName().fake(); - let city: String = fake::faker::address::en::CityName().fake(); - let country: String = fake::faker::address::en::CountryName().fake(); - let zip: String = fake::faker::address::en::ZipCode().fake(); - let account_id = Some(account.id); - let is_default: bool = true; - - let address = CreateAccountAddress { - name: Name::new(name.clone()), - email: Email::new(email.clone()), - phone: Phone::new(phone.clone()), - street: Street::new(street.clone()), - city: City::new(city.clone()), - country: Country::new(country.clone()), - zip: Zip::new(zip.clone()), - account_id, - is_default, - } - .run(&mut t) - .await - .unwrap(); - - assert_eq!( - address, - AccountAddress { - id: address.id, - name: Name::new(name.clone()), - email: Email::new(email.clone()), - phone: Phone::new(phone.clone()), - street: Street::new(street.clone()), - city: City::new(city.clone()), - country: Country::new(country.clone()), - zip: Zip::new(zip.clone()), - account_id: account.id, - is_default, - } - ); - address - }; - - let found = FindAccountAddress { - account_id: account.id, - address_id: address.id, - } - .run(&mut t) - .await - .unwrap(); - - assert_eq!(found, address); - - let changed = UpdateAccountAddress { - id: address.id, - name: address.name.clone(), - email: address.email.clone(), - phone: address.phone.clone(), - street: address.street.clone(), - city: address.city.clone(), - country: address.country.clone(), - zip: address.zip.clone(), - account_id: address.account_id, - is_default: true, - } - .run(&mut t) - .await - .unwrap(); - - address.is_default = true; - - assert_eq!(changed, address); - - let default_address = DefaultAccountAddress { - account_id: account.id, - } - .run(&mut t) - .await - .unwrap(); - - testx::db_rollback!(t); - assert_eq!(default_address, address); - } -} diff --git a/crates/account_manager/src/db/mod.rs b/crates/account_manager/src/db/mod.rs deleted file mode 100644 index d00f7b5..0000000 --- a/crates/account_manager/src/db/mod.rs +++ /dev/null @@ -1,31 +0,0 @@ -pub mod accounts; -pub mod addresses; - -pub use accounts::*; -pub use addresses::*; -use config::SharedAppConfig; -use sqlx::{Pool, Postgres}; - -#[derive(Clone)] -pub struct Database { - pub pool: sqlx::PgPool, - _config: SharedAppConfig, -} - -impl Database { - pub async fn build(config: SharedAppConfig) -> Self { - let url = config.lock().account_manager().database_url.clone(); - let pool = sqlx::PgPool::connect(&url).await.unwrap_or_else(|e| { - tracing::error!("Failed to connect to database. {e:?}"); - std::process::exit(1); - }); - Self { - pool, - _config: config, - } - } - - pub fn pool(&self) -> Pool { - self.pool.clone() - } -} diff --git a/crates/account_manager/src/idp.rs b/crates/account_manager/src/idp.rs deleted file mode 100644 index e3b6c55..0000000 --- a/crates/account_manager/src/idp.rs +++ /dev/null @@ -1,126 +0,0 @@ -use kanidm_client::{ClientError, KanidmClient}; -use kanidm_proto::internal::CUStatus; -use kanidm_proto::v1::Entry; - -pub async fn refresh_token(kanidm: &KanidmClient) -> Result<(), ClientError> { - kanidm - .auth_simple_password( - "idm_admin", - &std::env::var("KANIDM_IDM_ADMIN_PASS") - .expect("idm_admin password is requied, please set KANIDM_IDM_ADMIN_PASS"), - ) - .await?; - Ok(()) -} - -pub async fn create_account_with_password( - kanidm: &KanidmClient, - login: &str, - display_name: &str, - email: &str, - password: &str, -) -> Result<(), ClientError> { - refresh_token(kanidm).await?; - let _person_created = kanidm - .idm_person_account_create(login, display_name) - .await - .ok(); - let accounts = accounts(kanidm).await?; - let uid = find_account(&accounts, FindBy::Name(login)).await?; - let id = uid.to_string(); - - kanidm - .idm_person_account_update(&id, None, None, None, Some(&[email.to_string()])) - .await?; - let (session_token, status) = kanidm.idm_account_credential_update_begin(&id).await?; - tracing::debug!( - "Begin update credentials ({can_commit}): {status:?}", - can_commit = status.can_commit - ); - - kanidm - .idm_account_credential_update_set_password(&session_token, password) - .await?; - - let status = kanidm - .idm_account_credential_update_status(&session_token) - .await?; - tracing::debug!( - "Set password ({can_commit}): {status:?}", - can_commit = status.can_commit - ); - - let status = kanidm - .idm_account_credential_update_init_totp(&session_token) - .await?; - tracing::debug!( - "Init TOTP ({can_commit}): {status:?}", - can_commit = status.can_commit - ); - - // let status = kanidm - // .idm_account_credential_update_check_totp(&session_token, totp_chal, - // label) .await?; - - tracing::debug!( - "TOTP check ({can_commit}): {status:?}", - can_commit = status.can_commit - ); - - kanidm - .idm_account_credential_update_commit(&session_token) - .await?; - let status = kanidm - .idm_account_credential_update_status(&session_token) - .await?; - tracing::debug!( - "Commit ({can_commit}): {status:?}", - can_commit = status.can_commit - ); - Ok(()) -} - -pub async fn accounts(kanidm: &KanidmClient) -> Result, ClientError> { - refresh_token(kanidm).await?; - - kanidm.idm_person_account_list().await -} - -#[derive(Debug)] -pub enum FindBy<'s> { - Email(&'s str), - Name(&'s str), -} - -impl<'s> FindBy<'s> { - fn key(&self) -> &'static str { - match self { - Self::Email(..) => "mail", - Self::Name(..) => "name", - } - } - fn as_str(&self) -> &'s str { - match self { - Self::Email(s) => s, - Self::Name(s) => s, - } - } -} - -pub async fn find_account(list: &[Entry], find_by: FindBy<'_>) -> Result { - list.iter() - .find_map(|entra| { - tracing::debug!("compare {find_by:?} with {entra:?}"); - let attrs = &entra.attrs; - attrs.get(find_by.key()).filter(|v| { - tracing::debug!("compare value {v:?} with {s}", s = find_by.as_str()); - v.iter().any(|s| s == find_by.as_str()) - })?; - let id = attrs.get("uuid").and_then(|v| v.first())?; - id.parse::().ok() - }) - .ok_or_else(|| { - tracing::info!("User not found"); - ClientError::Unauthorized - }) -} diff --git a/crates/account_manager/src/main.rs b/crates/account_manager/src/main.rs deleted file mode 100644 index 905af98..0000000 --- a/crates/account_manager/src/main.rs +++ /dev/null @@ -1,61 +0,0 @@ -#![feature(structural_match)] - -use config::UpdateConfig; - -pub mod actions; -pub mod db; -pub mod idp; -pub mod mqtt; -pub mod rpc; - -pub type Result = std::result::Result; - -#[derive(Debug, Copy, Clone, serde::Serialize, thiserror::Error)] -pub enum Error { - #[error("Unable to send or receive msg from database")] - DbCritical, - #[error("Failed to load account data")] - Account, - #[error("Failed to load account addresses")] - Addresses, - #[error("Unable to save record")] - Saving, - #[error("Unable to hash password")] - Hashing, -} - -pub struct Opts {} - -impl UpdateConfig for Opts {} - -#[tokio::main] -async fn main() { - dotenv::dotenv().ok(); - config::init_tracing("account-manager"); - - let opts = Opts {}; - - let config = config::default_load(&opts); - - let db = db::Database::build(config.clone()).await; - - let kanidm = kanidm_client::KanidmClientBuilder::new() - .address(config.lock().account_manager().idm_url().to_owned()) - .danger_accept_invalid_certs(cfg!(debug_assertions)) - .connect_timeout(2) - .build() - .unwrap(); - idp::accounts(&kanidm).await.unwrap(); - idp::create_account_with_password( - &kanidm, - "eraden", - "Adrian Woźniak", - "adrian.wozniak@ita-prog.pl", - "n59GmOOdcpVUJqJ1", - ) - .await - .unwrap(); - - let mqtt_client = mqtt::start(config.clone(), db.clone()).await; - rpc::start(config.clone(), db.clone(), mqtt_client.clone()).await; -} diff --git a/crates/account_manager/src/mqtt.rs b/crates/account_manager/src/mqtt.rs deleted file mode 100644 index 25541dc..0000000 --- a/crates/account_manager/src/mqtt.rs +++ /dev/null @@ -1,30 +0,0 @@ -use config::SharedAppConfig; -use rumqttc::{Event, Incoming}; - -use crate::db::Database; - -pub async fn start(config: SharedAppConfig, _db: Database) -> channels::AsyncClient { - let (client, mut event_loop) = channels::accounts::mqtt::create_client(config); - - let spawn_client = client.clone(); - tokio::spawn(async move { - let _client = spawn_client.clone(); - loop { - let notification = event_loop.poll().await; - - match notification { - Ok(Event::Incoming(Incoming::Publish(publish))) => match publish.topic.as_str() { - _ => {} - }, - Ok(Event::Incoming(_incoming)) => {} - Ok(Event::Outgoing(_outgoing)) => {} - Err(e) => { - tracing::error!("{}", e); - } - } - } - // tracing::info!("Mqtt channel closed"); - }); - - client -} diff --git a/crates/account_manager/src/rpc.rs b/crates/account_manager/src/rpc.rs deleted file mode 100644 index c7bb512..0000000 --- a/crates/account_manager/src/rpc.rs +++ /dev/null @@ -1,86 +0,0 @@ -use channels::accounts::rpc::Accounts; -use channels::accounts::{all, find_by_identity, me, register}; -use channels::AsyncClient; -use config::SharedAppConfig; -use tarpc::context; - -use crate::actions; -use crate::db::Database; - -#[derive(Debug, Copy, Clone, serde::Serialize, thiserror::Error)] -#[serde(rename_all = "kebab-case", tag = "account")] -pub enum Error { - #[error("Unable to send or receive msg from database")] - DbCritical, - #[error("Failed to load account data")] - Account, - #[error("Failed to load account addresses")] - Addresses, - #[error("Unable to save record")] - Saving, - #[error("Unable to hash password")] - Hashing, -} - -#[derive(Clone)] -struct AccountsServer { - db: Database, - config: SharedAppConfig, - mqtt_client: AsyncClient, -} - -impl Accounts for AccountsServer { - async fn me(self, _: context::Context, input: me::Input) -> me::Output { - let res = actions::me(input.account_id, self.db).await; - tracing::info!("ME result: {:?}", res); - res - } - - async fn register_account( - self, - _: context::Context, - input: register::Input, - ) -> register::Output { - use channels::accounts::Error; - - let res = actions::create_account(input, &self.db, self.config).await; - tracing::info!("REGISTER result: {:?}", res); - match res { - Ok(account) => { - self.mqtt_client.emit_account_created(&account).await; - Ok(register::Details { account }) - } - Err(_e) => Err(Error::Account), - } - } - - async fn all(self, _: context::Context, input: all::Input) -> all::Output { - let res = actions::all(input, self.db).await; - tracing::info!("ME result: {:?}", res); - res - } - - async fn find_by_identity( - self, - _: context::Context, - input: find_by_identity::Input, - ) -> find_by_identity::Output { - let res = actions::find_by_identity(input, self.db).await; - tracing::info!("ME result: {:?}", res); - res - } -} - -pub async fn start(config: SharedAppConfig, db: Database, mqtt_client: AsyncClient) { - let port = { config.lock().account_manager().rpc_port }; - - channels::rpc::start("accounts", port, || { - AccountsServer { - db: db.clone(), - config: config.clone(), - mqtt_client: mqtt_client.clone(), - } - .serve() - }) - .await; -} diff --git a/crates/channels/src/accounts.rs b/crates/channels/src/accounts.rs index 84ddfe0..d096673 100644 --- a/crates/channels/src/accounts.rs +++ b/crates/channels/src/accounts.rs @@ -182,7 +182,7 @@ pub mod rpc { use tarpc::tokio_serde::formats::Bincode; let l = config.lock(); - let addr = l.account_manager().rpc_addr(); + let addr = l.idp().rpc_addr(); let transport = tarpc::serde_transport::tcp::connect(addr, Bincode::default); @@ -204,6 +204,6 @@ pub mod mqtt { use crate::AsyncClient; pub fn create_client(config: SharedAppConfig) -> (AsyncClient, EventLoop) { - crate::mqtt::create_client(CLIENT_NAME, config.lock().account_manager().mqtt_addr()) + crate::mqtt::create_client(CLIENT_NAME, config.lock().idp().mqtt_addr()) } } diff --git a/crates/channels/src/carts.rs b/crates/channels/src/carts.rs index f3425a6..4d34019 100644 --- a/crates/channels/src/carts.rs +++ b/crates/channels/src/carts.rs @@ -132,10 +132,7 @@ pub mod rpc { let addr = { let l = config.lock(); - ( - l.account_manager().rpc_bind.clone(), - l.account_manager().rpc_port, - ) + (l.idp().rpc_bind.clone(), l.idp().rpc_port) }; let transport = tarpc::serde_transport::tcp::connect(addr, Bincode::default); diff --git a/crates/config/src/lib.rs b/crates/config/src/lib.rs index 0b9d585..7f42f38 100644 --- a/crates/config/src/lib.rs +++ b/crates/config/src/lib.rs @@ -348,16 +348,18 @@ impl FilesConfig { } #[derive(Debug, Serialize, Deserialize)] -pub struct AccountManagerConfig { +pub struct IdpConfig { pub rpc_port: u16, pub rpc_bind: String, pub mqtt_port: u16, pub mqtt_bind: String, pub database_url: String, pub idm_url: String, + #[serde(default)] + pub secret: Option, } -impl Default for AccountManagerConfig { +impl Default for IdpConfig { fn default() -> Self { Self { rpc_port: 19329, @@ -366,13 +368,14 @@ impl Default for AccountManagerConfig { mqtt_bind: "0.0.0.0".into(), database_url: "postgres://postgres@localhost/myco_accounts".into(), idm_url: "https://localhost:8443".into(), + secret: Some("CHANGE ME".into()), } } } -impl Example for AccountManagerConfig {} +impl Example for IdpConfig {} -impl AccountManagerConfig { +impl IdpConfig { pub fn rpc_addr(&self) -> (&str, u16) { (&self.rpc_bind, self.rpc_port) } @@ -384,6 +387,10 @@ impl AccountManagerConfig { pub fn idm_url(&self) -> &str { &self.idm_url } + + pub fn secret(&self) -> Option<&String> { + self.secret.as_ref() + } } #[derive(Debug, Serialize, Deserialize)] @@ -668,7 +675,7 @@ impl TokensConfig { #[derive(Serialize, Deserialize)] pub struct AppConfig { #[serde(default)] - account_manager: AccountManagerConfig, + idp: IdpConfig, #[serde(default)] cart_manager: CartManagerConfig, #[serde(skip)] @@ -705,7 +712,7 @@ impl Example for AppConfig { database: DatabaseConfig::example(), search: SearchConfig::example(), files: FilesConfig::example(), - account_manager: AccountManagerConfig::example(), + idp: IdpConfig::example(), cart_manager: CartManagerConfig::example(), email_sender: EmailSenderConfig::example(), stocks: StocksConfig::example(), @@ -718,8 +725,8 @@ impl Example for AppConfig { } impl AppConfig { - pub fn account_manager(&self) -> &AccountManagerConfig { - &self.account_manager + pub fn idp(&self) -> &IdpConfig { + &self.idp } pub fn cart_manager(&self) -> &CartManagerConfig { @@ -800,7 +807,7 @@ impl Default for AppConfig { database: DatabaseConfig::default(), search: SearchConfig::default(), files: FilesConfig::default(), - account_manager: AccountManagerConfig::default(), + idp: IdpConfig::default(), cart_manager: CartManagerConfig::default(), email_sender: EmailSenderConfig::default(), stocks: StocksConfig::default(), diff --git a/myco.toml b/myco.toml index b362304..9ffaf81 100644 --- a/myco.toml +++ b/myco.toml @@ -1,4 +1,4 @@ -[account_manager] +[idp] rpc_port = 19329 rpc_bind = "0.0.0.0" mqtt_port = 1883