Add account me

This commit is contained in:
Adrian Woźniak 2022-05-20 16:08:49 +02:00
parent 0a3bc50d6c
commit c11c8f24f1
No known key found for this signature in database
GPG Key ID: 0012845A89C7352B
13 changed files with 227 additions and 44 deletions

96
Cargo.lock generated
View File

@ -8,6 +8,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"actix 0.13.0", "actix 0.13.0",
"actix-rt", "actix-rt",
"bus",
"chrono", "chrono",
"config", "config",
"database_manager", "database_manager",
@ -567,6 +568,15 @@ dependencies = [
"num-traits", "num-traits",
] ]
[[package]]
name = "atomic"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b88d82667eca772c4aa12f0f1348b3ae643424c8876448f3f7bd5787032e234c"
dependencies = [
"autocfg",
]
[[package]] [[package]]
name = "atty" name = "atty"
version = "0.2.14" version = "0.2.14"
@ -632,6 +642,7 @@ checksum = "dea908e7347a8c64e378c17e30ef880ad73e3b4498346b055c2c00ea342f3179"
name = "bazzar" name = "bazzar"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"account_manager",
"actix 0.13.0", "actix 0.13.0",
"actix-broker", "actix-broker",
"actix-cors", "actix-cors",
@ -781,6 +792,14 @@ version = "3.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899"
[[package]]
name = "bus"
version = "0.1.0"
dependencies = [
"lifeline",
"tokio",
]
[[package]] [[package]]
name = "byte-tools" name = "byte-tools"
version = "0.3.1" version = "0.3.1"
@ -814,6 +833,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"actix 0.13.0", "actix 0.13.0",
"actix-rt", "actix-rt",
"bus",
"chrono", "chrono",
"config", "config",
"database_manager", "database_manager",
@ -1888,14 +1908,6 @@ dependencies = [
"tokio-native-tls", "tokio-native-tls",
] ]
[[package]]
name = "i18n-files"
version = "0.1.0"
dependencies = [
"proc-macro2",
"syn",
]
[[package]] [[package]]
name = "ident_case" name = "ident_case"
version = "1.0.1" version = "1.0.1"
@ -2093,6 +2105,23 @@ dependencies = [
"vcpkg", "vcpkg",
] ]
[[package]]
name = "lifeline"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b49b836e2676e5f6d926c09dc1a13b52c3315b459554df4514d76756bfa72a0e"
dependencies = [
"anyhow",
"async-trait",
"futures-util",
"log",
"pin-project 0.4.29",
"postage",
"regex",
"thiserror",
"tokio",
]
[[package]] [[package]]
name = "local-channel" name = "local-channel"
version = "0.1.3" version = "0.1.3"
@ -2474,7 +2503,7 @@ dependencies = [
"js-sys", "js-sys",
"lazy_static", "lazy_static",
"percent-encoding", "percent-encoding",
"pin-project", "pin-project 1.0.10",
"rand", "rand",
"thiserror", "thiserror",
"tokio", "tokio",
@ -2712,13 +2741,33 @@ dependencies = [
"uncased", "uncased",
] ]
[[package]]
name = "pin-project"
version = "0.4.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9615c18d31137579e9ff063499264ddc1278e7b1982757ebc111028c4d1dc909"
dependencies = [
"pin-project-internal 0.4.29",
]
[[package]] [[package]]
name = "pin-project" name = "pin-project"
version = "1.0.10" version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e" checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e"
dependencies = [ dependencies = [
"pin-project-internal", "pin-project-internal 1.0.10",
]
[[package]]
name = "pin-project-internal"
version = "0.4.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "044964427019eed9d49d9d5bbce6047ef18f37100ea400912a9fa4a3523ab12a"
dependencies = [
"proc-macro2",
"quote",
"syn",
] ]
[[package]] [[package]]
@ -2750,6 +2799,12 @@ version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
[[package]]
name = "pollster"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5da3b0203fd7ee5720aa0b5e790b591aa5d3f41c3ed2c34a3a393382198af2f7"
[[package]] [[package]]
name = "polyval" name = "polyval"
version = "0.5.3" version = "0.5.3"
@ -2762,6 +2817,21 @@ dependencies = [
"universal-hash", "universal-hash",
] ]
[[package]]
name = "postage"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a63d25391d04a097954b76aba742b6b5b74f213dfe3dbaeeb36e8ddc1c657f0b"
dependencies = [
"atomic",
"crossbeam-queue",
"log",
"pin-project 1.0.10",
"pollster",
"static_assertions",
"thiserror",
]
[[package]] [[package]]
name = "ppv-lite86" name = "ppv-lite86"
version = "0.2.16" version = "0.2.16"
@ -3533,6 +3603,12 @@ dependencies = [
"version_check 0.9.4", "version_check 0.9.4",
] ]
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]] [[package]]
name = "stdweb" name = "stdweb"
version = "0.4.20" version = "0.4.20"

View File

@ -1,16 +1,10 @@
#[package]
#name = "bazzar"
#version = "0.1.0"
#edition = "2021"
#
#[[bin]]
#name = "api"
#path = "./api/src/main.rs"
[workspace] [workspace]
members = [ members = [
"api", # shared
"web",
"shared/model", "shared/model",
"shared/bus",
"shared/config",
# actors
"actors/account_manager", "actors/account_manager",
"actors/cart_manager", "actors/cart_manager",
"actors/database_manager", "actors/database_manager",
@ -20,8 +14,10 @@ members = [
"actors/search_manager", "actors/search_manager",
"actors/token_manager", "actors/token_manager",
"actors/fs_manager", "actors/fs_manager",
# artifacts
"db-seed", "db-seed",
"derive/i18n-files" "api",
"web",
] ]
[profile.release] [profile.release]

View File

@ -7,6 +7,7 @@ edition = "2021"
model = { path = "../../shared/model" } model = { path = "../../shared/model" }
config = { path = "../../shared/config" } config = { path = "../../shared/config" }
database_manager = { path = "../database_manager" } database_manager = { path = "../database_manager" }
bus = { path = "../../shared/bus" }
actix = { version = "0.13", features = [] } actix = { version = "0.13", features = [] }
actix-rt = { version = "2.7", features = [] } actix-rt = { version = "2.7", features = [] }

View File

@ -1,3 +1,65 @@
use database_manager::query_db;
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("Failed to load account data")]
Account,
#[error("Failed to load account addresses")]
Addresses,
}
pub type Result<T> = std::result::Result<T, Error>;
#[macro_export]
macro_rules! account_async_handler {
($msg: ty, $async: ident, $res: ty) => {
impl actix::Handler<$msg> for AccountManager {
type Result = actix::ResponseActFuture<Self, Result<$res>>;
fn handle(&mut self, msg: $msg, _ctx: &mut Self::Context) -> Self::Result {
use actix::WrapFuture;
let db = self.db.clone();
Box::pin(async { $async(msg, db).await }.into_actor(self))
}
}
};
}
#[macro_export]
macro_rules! query_account {
($cart: expr, $msg: expr, default $fail: expr) => {
match $cart.send($msg).await {
Ok(Ok(r)) => r,
Ok(Err(e)) => {
log::error!("{e}");
$fail
}
Err(e) => {
log::error!("{e:?}");
$fail
}
}
};
($cart: expr, $msg: expr, $fail: expr) => {
$crate::query_cart!($cart, $msg, $fail, $fail)
};
($cart: expr, $msg: expr, $db_fail: expr, $act_fail: expr) => {
match $cart.send($msg).await {
Ok(Ok(r)) => r,
Ok(Err(e)) => {
log::error!("{e}");
return Err($db_fail);
}
Err(e) => {
log::error!("{e:?}");
return Err($act_fail);
}
}
};
}
#[derive(Debug)] #[derive(Debug)]
pub struct AccountManager { pub struct AccountManager {
db: actix::Addr<database_manager::Database>, db: actix::Addr<database_manager::Database>,
@ -8,3 +70,38 @@ impl AccountManager {
Self { db } Self { db }
} }
} }
impl actix::Actor for AccountManager {
type Context = actix::Context<Self>;
}
pub struct MeResult {
pub account: model::FullAccount,
pub addresses: Vec<model::Address>,
}
#[derive(actix::Message, Debug)]
#[rtype(result = "Result<MeResult>")]
pub struct Me {
pub account_id: model::AccountId,
}
account_async_handler!(Me, me, MeResult);
pub(crate) async fn me(msg: Me, db: actix::Addr<database_manager::Database>) -> Result<MeResult> {
let account: model::FullAccount = query_db!(
db,
database_manager::FindAccount {
account_id: msg.account_id
},
Error::Account
);
let addresses = query_db!(
db,
database_manager::AccountAddresses {
account_id: msg.account_id
},
Error::Addresses
);
Ok(MeResult { account, addresses })
}

View File

@ -7,6 +7,7 @@ edition = "2021"
model = { path = "../../shared/model" } model = { path = "../../shared/model" }
config = { path = "../../shared/config" } config = { path = "../../shared/config" }
database_manager = { path = "../database_manager" } database_manager = { path = "../database_manager" }
bus = { path = "../../shared/bus" }
actix = { version = "0.13", features = [] } actix = { version = "0.13", features = [] }
actix-rt = { version = "2.7", features = [] } actix-rt = { version = "2.7", features = [] }

View File

@ -14,6 +14,7 @@ payment_manager = { path = "../actors/payment_manager" }
search_manager = { path = "../actors/search_manager" } search_manager = { path = "../actors/search_manager" }
token_manager = { path = "../actors/token_manager" } token_manager = { path = "../actors/token_manager" }
fs_manager = { path = "../actors/fs_manager" } fs_manager = { path = "../actors/fs_manager" }
account_manager = { path = "../actors/account_manager" }
human-panic = { version = "1.0.3" } human-panic = { version = "1.0.3" }

View File

@ -60,6 +60,7 @@ async fn server(opts: ServerOpts) -> Result<()> {
.await .await
.expect("Failed to initialize file system storage"); .expect("Failed to initialize file system storage");
let cart_manager = cart_manager::CartManager::new(db.clone()).start(); let cart_manager = cart_manager::CartManager::new(db.clone()).start();
let account_manager = account_manager::AccountManager::new(db.clone()).start();
let addr = { let addr = {
let l = app_config.lock(); let l = app_config.lock();
let w = l.web(); let w = l.web();
@ -89,6 +90,7 @@ async fn server(opts: ServerOpts) -> Result<()> {
.app_data(Data::new(search_manager.clone())) .app_data(Data::new(search_manager.clone()))
.app_data(Data::new(fs_manager.clone())) .app_data(Data::new(fs_manager.clone()))
.app_data(Data::new(cart_manager.clone())) .app_data(Data::new(cart_manager.clone()))
.app_data(Data::new(account_manager.clone()))
.configure(routes::configure) .configure(routes::configure)
.service({ .service({
let l = app_config.lock(); let l = app_config.lock();

View File

@ -1,3 +1,4 @@
use account_manager::query_account;
use actix::Addr; use actix::Addr;
use actix_web::web::{scope, Data, Json, ServiceConfig}; use actix_web::web::{scope, Data, Json, ServiceConfig};
use actix_web::{delete, get, post, put, HttpRequest, HttpResponse}; use actix_web::{delete, get, post, put, HttpRequest, HttpResponse};
@ -8,10 +9,10 @@ use model::api;
use payment_manager::{query_pay, PaymentManager}; use payment_manager::{query_pay, PaymentManager};
use token_manager::TokenManager; use token_manager::TokenManager;
use crate::routes;
use crate::routes::public::api_v1::{Error as ApiV1Error, ShoppingCartError}; use crate::routes::public::api_v1::{Error as ApiV1Error, ShoppingCartError};
use crate::routes::public::Error as PublicError; use crate::routes::public::Error as PublicError;
use crate::routes::{create_auth_pair, AuthPair, RequireUser, Result}; use crate::routes::{create_auth_pair, AuthPair, RequireUser, Result};
use crate::{public_send_db, routes};
/// This requires [model::AccessTokenString] to be set as bearer /// This requires [model::AccessTokenString] to be set as bearer
#[post("/token/verify")] #[post("/token/verify")]
@ -203,7 +204,7 @@ async fn delete_cart_item(
#[get("/me")] #[get("/me")]
pub(crate) async fn me( pub(crate) async fn me(
db: Data<Addr<Database>>, account: Data<Addr<account_manager::AccountManager>>,
tm: Data<Addr<TokenManager>>, tm: Data<Addr<TokenManager>>,
credentials: BearerAuth, credentials: BearerAuth,
) -> routes::Result<Json<model::api::Account>> { ) -> routes::Result<Json<model::api::Account>> {
@ -211,9 +212,12 @@ pub(crate) async fn me(
.require_user(tm.into_inner()) .require_user(tm.into_inner())
.await? .await?
.account_id(); .account_id();
let account: model::FullAccount = let account_manager::MeResult { account, addresses } = query_account!(
public_send_db!(owned, db, database_manager::FindAccount { account_id }); account,
let addresses = public_send_db!(owned, db, database_manager::AccountAddresses { account_id }); account_manager::Me { account_id },
PublicError::DatabaseConnection.into(),
PublicError::DatabaseConnection.into()
);
Ok(Json((account, addresses).into())) Ok(Json((account, addresses).into()))
} }

View File

@ -1,11 +0,0 @@
[package]
name = "i18n-files"
version = "0.1.0"
edition = "2021"
[lib]
proc-macro = true
[dependencies]
proc-macro2 = { version = "1.0.38" }
syn = { version = "1.0.94" }

View File

@ -1,7 +0,0 @@
extern crate proc_macro;
use proc_macro::TokenStream;
#[proc_macro]
pub fn lang(_item: TokenStream) -> TokenStream {
"fn answer() -> u32 { 42 }".parse().unwrap()
}

8
shared/bus/Cargo.toml Normal file
View File

@ -0,0 +1,8 @@
[package]
name = "bus"
version = "0.1.0"
edition = "2021"
[dependencies]
lifeline = { version = "0.6.1" }
tokio = { version = "1.18.2", features = ["full"] }

13
shared/bus/src/lib.rs Normal file
View File

@ -0,0 +1,13 @@
pub mod messages;
pub use lifeline;
use lifeline::lifeline_bus;
pub use lifeline::Message;
pub use tokio::sync::mpsc;
pub use crate::messages::*;
lifeline_bus!(pub struct MainBus);
// impl Message<MainBus> for MainSend {
// type Channel = mpsc::Sender<Self>;
// }

View File

@ -0,0 +1,2 @@
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum Main {}