refactoring
This commit is contained in:
parent
700b65ba2d
commit
a8726765e8
|
@ -28,7 +28,7 @@ tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
|
|||
tokio-cron-scheduler = { version = "0" }
|
||||
uuid = { version = "0", features = ["serde", "v4", "v5"] }
|
||||
|
||||
beteran-protobuf-rust = { git = "https://gitlab.loafle.net/bet/beteran-protobuf-rust.git", tag = "v0.1.23-snapshot" }
|
||||
beteran-common-rust = { git = "https://gitlab.loafle.net/bet/beteran-common-rust.git", tag = "v0.1.3-snapshot" }
|
||||
beteran-protobuf-rust = { git = "https://gitlab.loafle.net/bet/beteran-protobuf-rust.git", tag = "v0.1.24-snapshot" }
|
||||
beteran-common-rust = { git = "https://gitlab.loafle.net/bet/beteran-common-rust.git", tag = "v0.1.4-snapshot" }
|
||||
|
||||
[build-dependencies]
|
||||
|
|
118
src/compositions/member/composition.rs
Normal file
118
src/compositions/member/composition.rs
Normal file
|
@ -0,0 +1,118 @@
|
|||
//!
|
||||
//!
|
||||
|
||||
use diesel::{result::Error, sql_query, RunQueryDsl};
|
||||
|
||||
use super::models;
|
||||
|
||||
pub struct Composition {}
|
||||
|
||||
impl std::fmt::Debug for Composition {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
f.debug_struct("Composition of members").finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Composition {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Composition {
|
||||
///
|
||||
pub fn new() -> Composition {
|
||||
Composition {}
|
||||
}
|
||||
|
||||
///
|
||||
pub fn select(
|
||||
&self,
|
||||
conn: &diesel::PgConnection,
|
||||
id: uuid::Uuid,
|
||||
) -> Result<Option<models::Member>, Error> {
|
||||
match sql_query(
|
||||
"
|
||||
SELECT
|
||||
m.id as m_id,
|
||||
m.site_id as m_site_id,
|
||||
m.member_class_id as m_member_class_id,
|
||||
m.member_level_id as m_member_level_id,
|
||||
m.username as m_username,
|
||||
m.password as m_password,
|
||||
m.nickname as m_nickname,
|
||||
m.mobile_phone_number as m_mobile_phone_number,
|
||||
m.state as m_state,
|
||||
m.state_changed_at as m_state_changed_at,
|
||||
m.referrer_member_id as m_referrer_member_id,
|
||||
m.referred_count as m_referred_count,
|
||||
m.last_signined_ip as m_last_signined_ip,
|
||||
m.last_signined_at as m_last_signined_at,
|
||||
m.created_at as m_created_at,
|
||||
m.updated_at as m_updated_at,
|
||||
m.deleted_at as m_deleted_at,
|
||||
|
||||
s.id as s_id,
|
||||
s.url as s_url,
|
||||
s.show as s_show,
|
||||
s.can_use as s_can_use,
|
||||
s.created_at as s_created_at,
|
||||
s.updated_at as s_updated_at,
|
||||
s.deleted_at as s_deleted_at,
|
||||
|
||||
mc.id as mc_id,
|
||||
mc.parent_id as mc_parent_id,
|
||||
mc.name as mc_name,
|
||||
mc.created_at as mc_created_at,
|
||||
mc.updated_at as mc_updated_at,
|
||||
mc.deleted_at as mc_deleted_at,
|
||||
|
||||
ml.id as ml_id,
|
||||
ml.name as ml_name,
|
||||
ml.sort_order as ml_sort_order,
|
||||
ml.created_at as ml_created_at,
|
||||
ml.updated_at as ml_updated_at,
|
||||
ml.deleted_at as ml_deleted_at,
|
||||
|
||||
_m.id as _m_id,
|
||||
_m.member_site_id as _m_member_site_id,
|
||||
_m.member_class_id as _m_member_class_id,
|
||||
_m.member_level_id as _m_member_level_id,
|
||||
_m.username as _m_username,
|
||||
_m.password as _m_password,
|
||||
_m.nickname as _m_nickname,
|
||||
_m.mobile_phone_number as _m_mobile_phone_number,
|
||||
_m.state as _m_state,
|
||||
_m.state_changed_at as _m_state_changed_at,
|
||||
_m.referrer_member_id as _m_referrer_member_id,
|
||||
_m.referred_count as _m_referred_count,
|
||||
_m.last_signined_ip as _m_last_signined_ip,
|
||||
_m.last_signined_at as _m_last_signined_at,
|
||||
_m.created_at as _m_created_at,
|
||||
_m.updated_at as _m_updated_at,
|
||||
_m.deleted_at as _m_deleted_at
|
||||
|
||||
FROM members as m
|
||||
JOIN sites s
|
||||
ON s.id = m.site_id
|
||||
JOIN member_classes mc
|
||||
ON mc.id = m.member_class_id
|
||||
JOIN member_levels ml
|
||||
ON ml.id = m.member_level_id
|
||||
JOIN members _m
|
||||
ON _m.id = m.referrer_member_id
|
||||
WHERE
|
||||
m.id = $1
|
||||
",
|
||||
)
|
||||
.bind::<diesel::sql_types::Uuid, _>(id)
|
||||
.get_result::<models::Member>(conn)
|
||||
{
|
||||
Ok(m) => Ok(Some(m)),
|
||||
Err(e) => match e {
|
||||
diesel::result::Error::NotFound => Ok(None),
|
||||
_ => Err(e),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
7
src/compositions/member/mod.rs
Normal file
7
src/compositions/member/mod.rs
Normal file
|
@ -0,0 +1,7 @@
|
|||
//!
|
||||
//!
|
||||
|
||||
///
|
||||
pub mod composition;
|
||||
///
|
||||
pub mod models;
|
113
src/compositions/member/models.rs
Normal file
113
src/compositions/member/models.rs
Normal file
|
@ -0,0 +1,113 @@
|
|||
//!
|
||||
//!
|
||||
use crate::repositories::{
|
||||
member::models::Member as _Member, member::schema::MemberState as _MemberState,
|
||||
member_class::models::MemberClass as _MemberClass,
|
||||
member_level::models::MemberLevel as _MemberLevel, site::models::Site as _Site,
|
||||
};
|
||||
use diesel::deserialize::QueryableByName;
|
||||
|
||||
///
|
||||
#[derive(Eq, Hash, PartialEq, Debug, Clone)]
|
||||
pub struct Member {
|
||||
///
|
||||
pub id: uuid::Uuid,
|
||||
///
|
||||
pub site: _Site,
|
||||
///
|
||||
pub member_class: _MemberClass,
|
||||
///
|
||||
pub member_level: _MemberLevel,
|
||||
///
|
||||
pub username: String,
|
||||
///
|
||||
pub password: String,
|
||||
///
|
||||
pub nickname: String,
|
||||
///
|
||||
pub mobile_phone_number: Option<String>,
|
||||
///
|
||||
pub state: _MemberState,
|
||||
///
|
||||
pub state_changed_at: Option<i64>,
|
||||
///
|
||||
pub referrer_member: Option<_Member>,
|
||||
///
|
||||
pub referred_count: i64,
|
||||
///
|
||||
pub last_signined_ip: Option<String>,
|
||||
///
|
||||
pub last_signined_at: Option<i64>,
|
||||
///
|
||||
pub created_at: i64,
|
||||
///
|
||||
pub updated_at: i64,
|
||||
///
|
||||
pub deleted_at: Option<i64>,
|
||||
}
|
||||
|
||||
impl QueryableByName<diesel::pg::Pg> for Member {
|
||||
fn build<R: diesel::row::NamedRow<diesel::pg::Pg>>(row: &R) -> diesel::deserialize::Result<Self> {
|
||||
let referrer_member = _Member {
|
||||
id: row.get("_m_id")?,
|
||||
site_id: row.get("_m_site_id")?,
|
||||
member_class_id: row.get("_m_member_class_id")?,
|
||||
member_level_id: row.get("_m_member_level_id")?,
|
||||
username: row.get("_m_username")?,
|
||||
password: row.get("_m_password")?,
|
||||
nickname: row.get("_m_nickname")?,
|
||||
mobile_phone_number: row.get("_m_mobile_phone_number")?,
|
||||
state: row.get("_m_state")?,
|
||||
state_changed_at: row.get("_m_state_changed_at")?,
|
||||
referrer_member_id: row.get("_m_referrer_member_id")?,
|
||||
referred_count: row.get("_m_referred_count")?,
|
||||
last_signined_ip: row.get("_m_last_signined_ip")?,
|
||||
last_signined_at: row.get("_m_last_signined_at")?,
|
||||
created_at: row.get("_m_created_at")?,
|
||||
updated_at: row.get("_m_updated_at")?,
|
||||
deleted_at: row.get("_m_deleted_at")?,
|
||||
};
|
||||
|
||||
Ok(Member {
|
||||
id: row.get("m_id")?,
|
||||
site: _Site {
|
||||
id: row.get("s_id")?,
|
||||
url: row.get("s_url")?,
|
||||
show: row.get("s_show")?,
|
||||
can_use: row.get("s_can_use")?,
|
||||
created_at: row.get("s_created_at")?,
|
||||
updated_at: row.get("s_updated_at")?,
|
||||
deleted_at: row.get("s_deleted_at")?,
|
||||
},
|
||||
member_class: _MemberClass {
|
||||
id: row.get("mc_id")?,
|
||||
parent_id: row.get("mc_parent_id")?,
|
||||
name: row.get("mc_name")?,
|
||||
created_at: row.get("mc_created_at")?,
|
||||
updated_at: row.get("mc_updated_at")?,
|
||||
deleted_at: row.get("mc_deleted_at")?,
|
||||
},
|
||||
member_level: _MemberLevel {
|
||||
id: row.get("ml_id")?,
|
||||
name: row.get("ml_name")?,
|
||||
sort_order: row.get("ml_sort_order")?,
|
||||
created_at: row.get("ml_created_at")?,
|
||||
updated_at: row.get("ml_updated_at")?,
|
||||
deleted_at: row.get("ml_deleted_at")?,
|
||||
},
|
||||
username: row.get("m_username")?,
|
||||
password: row.get("m_password")?,
|
||||
nickname: row.get("m_nickname")?,
|
||||
mobile_phone_number: row.get("m_mobile_phone_number")?,
|
||||
state: row.get("m_state")?,
|
||||
state_changed_at: row.get("m_state_changed_at")?,
|
||||
referrer_member: None,
|
||||
referred_count: row.get("m_referred_count")?,
|
||||
last_signined_ip: row.get("m_last_signined_ip")?,
|
||||
last_signined_at: row.get("m_last_signined_at")?,
|
||||
created_at: row.get("m_created_at")?,
|
||||
updated_at: row.get("m_updated_at")?,
|
||||
deleted_at: row.get("m_deleted_at")?,
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
pub mod member;
|
||||
pub mod site;
|
62
src/compositions/site/composition.rs
Normal file
62
src/compositions/site/composition.rs
Normal file
|
@ -0,0 +1,62 @@
|
|||
//!
|
||||
//!
|
||||
|
||||
use super::models;
|
||||
use crate::repositories;
|
||||
use diesel::{result::Error, sql_query, RunQueryDsl};
|
||||
|
||||
pub struct Composition {
|
||||
site_repository: repositories::site::repository::Repository,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for Composition {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
f.debug_struct("Composition of members").finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Composition {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Composition {
|
||||
///
|
||||
pub fn new() -> Composition {
|
||||
Composition {
|
||||
site_repository: repositories::site::repository::Repository::new(),
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
pub fn select_by_url(
|
||||
&self,
|
||||
conn: &diesel::PgConnection,
|
||||
url: Option<String>,
|
||||
site_id: uuid::Uuid,
|
||||
) -> Result<Option<repositories::site::models::Site>, Error> {
|
||||
let site_url = match url {
|
||||
Some(site_url) => site_url,
|
||||
None => {
|
||||
return Ok(None);
|
||||
}
|
||||
};
|
||||
let ms = match self.site_repository.select(conn, site_id)? {
|
||||
Some(s) => s,
|
||||
None => {
|
||||
return Ok(None);
|
||||
}
|
||||
};
|
||||
|
||||
if ms.url.eq("*") {
|
||||
return Ok(Some(ms));
|
||||
}
|
||||
|
||||
if !ms.url.eq(&site_url) {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
Ok(Some(ms))
|
||||
}
|
||||
}
|
7
src/compositions/site/mod.rs
Normal file
7
src/compositions/site/mod.rs
Normal file
|
@ -0,0 +1,7 @@
|
|||
//!
|
||||
//!
|
||||
|
||||
///
|
||||
pub mod composition;
|
||||
///
|
||||
pub mod models;
|
1
src/compositions/site/models.rs
Normal file
1
src/compositions/site/models.rs
Normal file
|
@ -0,0 +1 @@
|
|||
|
|
@ -27,10 +27,18 @@ impl Repository {
|
|||
}
|
||||
|
||||
///
|
||||
pub fn select(&self, conn: &diesel::PgConnection, id: uuid::Uuid) -> Result<models::Site, Error> {
|
||||
sites::table
|
||||
.find(id as uuid::Uuid)
|
||||
.first::<models::Site>(conn)
|
||||
pub fn select(
|
||||
&self,
|
||||
conn: &diesel::PgConnection,
|
||||
id: uuid::Uuid,
|
||||
) -> Result<Option<models::Site>, Error> {
|
||||
match sites::table.find(id).first::<models::Site>(conn) {
|
||||
Ok(m) => Ok(Some(m)),
|
||||
Err(e) => match e {
|
||||
diesel::result::Error::NotFound => Ok(None),
|
||||
_ => Err(e),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
//!
|
||||
//!
|
||||
|
||||
use super::super::super::compositions;
|
||||
use super::super::super::repositories;
|
||||
use beteran_common_rust as bcr;
|
||||
use beteran_protobuf_rust as bpr;
|
||||
|
@ -16,8 +17,9 @@ pub struct Service<'a> {
|
|||
queue_broker: String,
|
||||
pool: Pool<ConnectionManager<PgConnection>>,
|
||||
member_repository: repositories::member::repository::Repository,
|
||||
member_site_repository: repositories::site::repository::Repository,
|
||||
member_session_repository: repositories::member_session::repository::Repository,
|
||||
site_repository: repositories::site::repository::Repository,
|
||||
site_composition: compositions::site::composition::Composition,
|
||||
argon2_config: argon2::Config<'a>,
|
||||
captcha_salt: String,
|
||||
password_salt: String,
|
||||
|
@ -44,8 +46,9 @@ impl Service<'_> {
|
|||
queue_broker,
|
||||
pool,
|
||||
member_repository: repositories::member::repository::Repository::new(),
|
||||
member_site_repository: repositories::site::repository::Repository::new(),
|
||||
member_session_repository: repositories::member_session::repository::Repository::new(),
|
||||
site_repository: repositories::site::repository::Repository::new(),
|
||||
site_composition: compositions::site::composition::Composition::new(),
|
||||
argon2_config: argon2::Config::default(),
|
||||
captcha_salt,
|
||||
password_salt,
|
||||
|
@ -62,6 +65,38 @@ impl Service<'_> {
|
|||
.map(|_| ())
|
||||
}
|
||||
|
||||
fn check_site(
|
||||
&self,
|
||||
conn: &diesel::PgConnection,
|
||||
url: Option<String>,
|
||||
site_id: uuid::Uuid,
|
||||
) -> Result<repositories::site::models::Site, bcr::error::rpc::Error> {
|
||||
match self
|
||||
.site_composition
|
||||
.select_by_url(conn, url, site_id)
|
||||
.map_err(|e| {
|
||||
bcr::error::rpc::Error::Server(bcr::error::rpc::Server {
|
||||
code: bpr::protobuf::rpc::Error::SERVER_00,
|
||||
message: format!("server {}", e),
|
||||
data: None,
|
||||
})
|
||||
})? {
|
||||
Some(s) => Ok(s),
|
||||
None => Err(bcr::error::rpc::Error::InvalidParams(
|
||||
bcr::error::rpc::InvalidParams {
|
||||
message: "invalid site_url information".to_string(),
|
||||
detail: bcr::error::rpc::InvalidParamsDetail {
|
||||
location: "request".to_string(),
|
||||
param: "client.site_url".to_string(),
|
||||
value: "".to_string(),
|
||||
error_type: bcr::error::rpc::InvalidParamsType::None,
|
||||
message: "".to_string(),
|
||||
},
|
||||
},
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
async fn check_username_for_duplication(&self) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let s = self
|
||||
.connection_broker
|
||||
|
@ -274,7 +309,7 @@ impl Service<'_> {
|
|||
})
|
||||
})?;
|
||||
|
||||
let client = match req.client {
|
||||
let _client = match req.client {
|
||||
Some(c) => c,
|
||||
None => {
|
||||
return Err(bcr::error::rpc::Error::InvalidParams(
|
||||
|
@ -292,59 +327,6 @@ impl Service<'_> {
|
|||
}
|
||||
};
|
||||
|
||||
// let site_url = match client.site_url {
|
||||
// Some(site_url) => site_url,
|
||||
// None => {
|
||||
// return Err(bcr::error::rpc::Error::InvalidParams(
|
||||
// bcr::error::rpc::InvalidParams {
|
||||
// message: "invalid site_url information".to_string(),
|
||||
// detail: bcr::error::rpc::InvalidParamsDetail {
|
||||
// location: "request".to_string(),
|
||||
// param: "client.site_url".to_string(),
|
||||
// value: "".to_string(),
|
||||
// error_type: bcr::error::rpc::InvalidParamsType::Required,
|
||||
// message: "".to_string(),
|
||||
// },
|
||||
// },
|
||||
// ));
|
||||
// }
|
||||
// };
|
||||
|
||||
let conn = self.pool.get().map_err(|e| {
|
||||
bcr::error::rpc::Error::Server(bcr::error::rpc::Server {
|
||||
code: bpr::protobuf::rpc::Error::SERVER_00,
|
||||
message: format!("server {}", e),
|
||||
data: None,
|
||||
})
|
||||
})?;
|
||||
|
||||
// match self
|
||||
// .member_site_repository
|
||||
// .select_by_url(&conn, &site_url)
|
||||
// .map_err(|e| {
|
||||
// bcr::error::rpc::Error::Server(bcr::error::rpc::Server {
|
||||
// code: bpr::protobuf::rpc::Error::SERVER_00,
|
||||
// message: format!("server {}", e),
|
||||
// data: None,
|
||||
// })
|
||||
// })? {
|
||||
// Some(ms) => ms,
|
||||
// None => {
|
||||
// return Err(bcr::error::rpc::Error::InvalidParams(
|
||||
// bcr::error::rpc::InvalidParams {
|
||||
// message: "invalid site_url information".to_string(),
|
||||
// detail: bcr::error::rpc::InvalidParamsDetail {
|
||||
// location: "request".to_string(),
|
||||
// param: "client.site_url".to_string(),
|
||||
// value: "".to_string(),
|
||||
// error_type: bcr::error::rpc::InvalidParamsType::None,
|
||||
// message: "".to_string(),
|
||||
// },
|
||||
// },
|
||||
// ));
|
||||
// }
|
||||
// };
|
||||
|
||||
let mut c = captcha::Captcha::new();
|
||||
|
||||
let c = c
|
||||
|
@ -454,33 +436,6 @@ impl Service<'_> {
|
|||
})
|
||||
})?;
|
||||
|
||||
let ms = match self
|
||||
.member_site_repository
|
||||
.select_by_url(&conn, client.site_url())
|
||||
.map_err(|e| {
|
||||
bcr::error::rpc::Error::Server(bcr::error::rpc::Server {
|
||||
code: bpr::protobuf::rpc::Error::SERVER_00,
|
||||
message: format!("server {}", e),
|
||||
data: None,
|
||||
})
|
||||
})? {
|
||||
Some(ms) => ms,
|
||||
None => {
|
||||
return Err(bcr::error::rpc::Error::InvalidParams(
|
||||
bcr::error::rpc::InvalidParams {
|
||||
message: "invalid site_url information".to_string(),
|
||||
detail: bcr::error::rpc::InvalidParamsDetail {
|
||||
location: "request".to_string(),
|
||||
param: "client.site_url".to_string(),
|
||||
value: "".to_string(),
|
||||
error_type: bcr::error::rpc::InvalidParamsType::None,
|
||||
message: "".to_string(),
|
||||
},
|
||||
},
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
let security_code_hash = req.security_code_hash;
|
||||
let security_code = req.security_code;
|
||||
let username = req.username;
|
||||
|
@ -544,21 +499,6 @@ impl Service<'_> {
|
|||
}
|
||||
};
|
||||
|
||||
if m.site_id != ms.id {
|
||||
return Err(bcr::error::rpc::Error::InvalidParams(
|
||||
bcr::error::rpc::InvalidParams {
|
||||
message: "invalid site_url".to_string(),
|
||||
detail: bcr::error::rpc::InvalidParamsDetail {
|
||||
location: "header".to_string(),
|
||||
param: "client.site_url".to_string(),
|
||||
value: client.site_url().to_string(),
|
||||
error_type: bcr::error::rpc::InvalidParamsType::EqualsTo,
|
||||
message: "".to_string(),
|
||||
},
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
if !(argon2::verify_encoded(&m.password, password.as_bytes()).map_err(|e| {
|
||||
bcr::error::rpc::Error::InvalidParams(bcr::error::rpc::InvalidParams {
|
||||
message: "invalid password".to_string(),
|
||||
|
@ -585,6 +525,8 @@ impl Service<'_> {
|
|||
));
|
||||
}
|
||||
|
||||
let _s = self.check_site(&conn, client.site_url.clone(), m.site_id)?;
|
||||
|
||||
let expires_at = (chrono::Utc::now() + chrono::Duration::minutes(30)).timestamp();
|
||||
let session = self
|
||||
.member_session_repository
|
||||
|
|
Loading…
Reference in New Issue
Block a user