captcha repository is removed
This commit is contained in:
parent
fb1b451959
commit
81ac84043b
4
.vscode/launch.json
vendored
4
.vscode/launch.json
vendored
|
@ -23,6 +23,8 @@
|
||||||
"URL_DATABASE": "postgresql://beteran:qwer5795QWER@192.168.50.200:25432/beteran",
|
"URL_DATABASE": "postgresql://beteran:qwer5795QWER@192.168.50.200:25432/beteran",
|
||||||
"URL_BROKER": "nats://192.168.50.200:4222",
|
"URL_BROKER": "nats://192.168.50.200:4222",
|
||||||
"QUEUE_BROKER": "bet.beteran",
|
"QUEUE_BROKER": "bet.beteran",
|
||||||
|
"CAPTCHA_SALT": "qwer5795QWER",
|
||||||
|
"PASSWORD_SALT": "qwer5795QWER",
|
||||||
},
|
},
|
||||||
"args": [],
|
"args": [],
|
||||||
"cwd": "${workspaceFolder}"
|
"cwd": "${workspaceFolder}"
|
||||||
|
@ -47,6 +49,8 @@
|
||||||
"URL_DATABASE": "postgresql://beteran:qwer5795QWER@192.168.50.200:25432/beteran",
|
"URL_DATABASE": "postgresql://beteran:qwer5795QWER@192.168.50.200:25432/beteran",
|
||||||
"URL_BROKER": "nats://192.168.50.200:4222",
|
"URL_BROKER": "nats://192.168.50.200:4222",
|
||||||
"QUEUE_BROKER": "bet.beteran",
|
"QUEUE_BROKER": "bet.beteran",
|
||||||
|
"CAPTCHA_SALT": "qwer5795QWER",
|
||||||
|
"PASSWORD_SALT": "qwer5795QWER",
|
||||||
},
|
},
|
||||||
"args": [],
|
"args": [],
|
||||||
"cwd": "${workspaceFolder}"
|
"cwd": "${workspaceFolder}"
|
||||||
|
|
|
@ -28,7 +28,7 @@ tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
|
||||||
tokio-cron-scheduler = { version = "0" }
|
tokio-cron-scheduler = { version = "0" }
|
||||||
uuid = { version = "0", features = ["serde", "v4", "v5"] }
|
uuid = { version = "0", features = ["serde", "v4", "v5"] }
|
||||||
|
|
||||||
beteran-protobuf-rust = { git = "https://gitlab.loafle.net/bet/beteran-protobuf-rust.git", tag = "v0.1.22-snapshot" }
|
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.2-snapshot" }
|
beteran-common-rust = { git = "https://gitlab.loafle.net/bet/beteran-common-rust.git", tag = "v0.1.3-snapshot" }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
DROP UNIQUE INDEX uidx_captchas_token;
|
|
||||||
DROP TABLE captchas;
|
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
CREATE TABLE IF NOT EXISTS captchas (
|
|
||||||
id UUID DEFAULT uuid_generate_v4(),
|
|
||||||
token TEXT NOT NULL,
|
|
||||||
security_code TEXT NOT NULL,
|
|
||||||
expires_at BIGINT NOT NULL DEFAULT (extract(epoch from now()) * 1000),
|
|
||||||
created_at BIGINT NOT NULL DEFAULT (extract(epoch from now()) * 1000),
|
|
||||||
|
|
||||||
PRIMARY KEY (id)
|
|
||||||
);
|
|
||||||
|
|
||||||
-- index
|
|
||||||
CREATE UNIQUE INDEX uidx_captchas_token ON captchas (token);
|
|
11
src/main.rs
11
src/main.rs
|
@ -34,6 +34,15 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
None => "".to_string(),
|
None => "".to_string(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let captcha_salt = match env::var_os("CAPTCHA_SALT") {
|
||||||
|
Some(v) => v.into_string().unwrap(),
|
||||||
|
None => "".to_string(),
|
||||||
|
};
|
||||||
|
let password_salt = match env::var_os("PASSWORD_SALT") {
|
||||||
|
Some(v) => v.into_string().unwrap(),
|
||||||
|
None => "".to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
let manager = ConnectionManager::<PgConnection>::new(url_db);
|
let manager = ConnectionManager::<PgConnection>::new(url_db);
|
||||||
let pool = Pool::builder()
|
let pool = Pool::builder()
|
||||||
.max_size(4)
|
.max_size(4)
|
||||||
|
@ -50,6 +59,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
connection_server_broker.clone(),
|
connection_server_broker.clone(),
|
||||||
queue_server_broker.clone(),
|
queue_server_broker.clone(),
|
||||||
pool.clone(),
|
pool.clone(),
|
||||||
|
captcha_salt.clone(),
|
||||||
|
password_salt.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
println!("Server service [beteran-server-service] is started");
|
println!("Server service [beteran-server-service] is started");
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
//!
|
|
||||||
//!
|
|
||||||
|
|
||||||
///
|
|
||||||
pub mod models;
|
|
||||||
///
|
|
||||||
pub mod repository;
|
|
||||||
///
|
|
||||||
pub mod schema;
|
|
|
@ -1,37 +0,0 @@
|
||||||
use super::schema::captchas;
|
|
||||||
use beteran_common_rust as bcr;
|
|
||||||
|
|
||||||
///
|
|
||||||
#[derive(Eq, Hash, Identifiable, Queryable, PartialEq, Debug, Clone)]
|
|
||||||
#[table_name = "captchas"]
|
|
||||||
pub struct Captcha {
|
|
||||||
///
|
|
||||||
pub id: uuid::Uuid,
|
|
||||||
///
|
|
||||||
pub security_code: String,
|
|
||||||
///
|
|
||||||
pub expires_at: i64,
|
|
||||||
///
|
|
||||||
pub created_at: i64,
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
#[derive(Insertable, Debug, Clone)]
|
|
||||||
#[table_name = "captchas"]
|
|
||||||
pub struct NewCaptcha {
|
|
||||||
///
|
|
||||||
pub security_code: String,
|
|
||||||
///
|
|
||||||
pub expires_at: i64,
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct FindAll {
|
|
||||||
///
|
|
||||||
pub expires_at: Option<i64>,
|
|
||||||
///
|
|
||||||
pub pagination: Option<bcr::models::pagination::Pagination>,
|
|
||||||
///
|
|
||||||
pub sorts: Option<Vec<bcr::models::pagination::Sort>>,
|
|
||||||
}
|
|
|
@ -1,135 +0,0 @@
|
||||||
//!
|
|
||||||
//!
|
|
||||||
use super::{models, schema::captchas};
|
|
||||||
use beteran_common_rust as bcr;
|
|
||||||
use diesel::prelude::*;
|
|
||||||
use diesel::result::Error;
|
|
||||||
|
|
||||||
///
|
|
||||||
pub struct Repository {}
|
|
||||||
|
|
||||||
impl std::fmt::Debug for Repository {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
||||||
f.debug_struct("Repository of captchas").finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Repository {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Repository {
|
|
||||||
///
|
|
||||||
pub fn new() -> Repository {
|
|
||||||
Repository {}
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
pub fn insert(
|
|
||||||
&self,
|
|
||||||
conn: &diesel::PgConnection,
|
|
||||||
new_captcha: &models::NewCaptcha,
|
|
||||||
) -> Result<models::Captcha, Error> {
|
|
||||||
let captcha = diesel::insert_into(captchas::table)
|
|
||||||
.values(new_captcha)
|
|
||||||
.get_result::<models::Captcha>(conn)?;
|
|
||||||
|
|
||||||
Ok(captcha)
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
pub fn select(
|
|
||||||
&self,
|
|
||||||
conn: &diesel::PgConnection,
|
|
||||||
id: uuid::Uuid,
|
|
||||||
) -> Result<Option<models::Captcha>, Error> {
|
|
||||||
match captchas::table.find(id).first::<models::Captcha>(conn) {
|
|
||||||
Ok(m) => Ok(Some(m)),
|
|
||||||
Err(e) => match e {
|
|
||||||
diesel::result::Error::NotFound => Ok(None),
|
|
||||||
_ => Err(e),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
pub fn select_all_count(
|
|
||||||
&self,
|
|
||||||
conn: &diesel::PgConnection,
|
|
||||||
find_all: models::FindAll,
|
|
||||||
) -> Result<i64, Error> {
|
|
||||||
use captchas::dsl;
|
|
||||||
|
|
||||||
let mut q = captchas::table.into_boxed();
|
|
||||||
|
|
||||||
if let Some(sp) = find_all.expires_at {
|
|
||||||
q = q.filter(dsl::expires_at.lt(sp));
|
|
||||||
}
|
|
||||||
|
|
||||||
q.count().get_result(conn)
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
pub fn select_all(
|
|
||||||
&self,
|
|
||||||
conn: &diesel::PgConnection,
|
|
||||||
find_all: models::FindAll,
|
|
||||||
) -> Result<Vec<models::Captcha>, Error> {
|
|
||||||
use captchas::dsl;
|
|
||||||
|
|
||||||
let mut q = captchas::table.into_boxed();
|
|
||||||
|
|
||||||
if let Some(sp) = find_all.expires_at {
|
|
||||||
q = q.filter(dsl::expires_at.lt(sp));
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(p) = find_all.pagination {
|
|
||||||
let page = p.page.unwrap_or(1);
|
|
||||||
|
|
||||||
if let Some(page_size) = p.page_size {
|
|
||||||
q = q.offset(((page - 1) * page_size) as i64);
|
|
||||||
q = q.limit(page_size as i64);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let Some(orderbys) = find_all.sorts {
|
|
||||||
for s in orderbys {
|
|
||||||
match s {
|
|
||||||
bcr::models::pagination::Sort::ASC(property) => match property.as_str() {
|
|
||||||
"expires_at" => {
|
|
||||||
q = q.order_by(dsl::expires_at.asc());
|
|
||||||
}
|
|
||||||
"created_at" => {
|
|
||||||
q = q.order_by(dsl::created_at.asc());
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => {}
|
|
||||||
},
|
|
||||||
bcr::models::pagination::Sort::DESC(property) => match property.as_str() {
|
|
||||||
"expires_at" => {
|
|
||||||
q = q.order_by(dsl::expires_at.desc());
|
|
||||||
}
|
|
||||||
"created_at" => {
|
|
||||||
q = q.order_by(dsl::created_at.desc());
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
q.load::<models::Captcha>(conn)
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
pub fn delete_expired(&self, conn: &diesel::PgConnection) -> Result<u64, Error> {
|
|
||||||
use captchas::dsl;
|
|
||||||
|
|
||||||
let now = chrono::Utc::now().timestamp();
|
|
||||||
|
|
||||||
diesel::delete(dsl::captchas.filter(dsl::expires_at.le(now)))
|
|
||||||
.execute(conn)
|
|
||||||
.map(|c| c as u64)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
//!
|
|
||||||
//!
|
|
||||||
|
|
||||||
table! {
|
|
||||||
///
|
|
||||||
captchas(id) {
|
|
||||||
///
|
|
||||||
id -> Uuid,
|
|
||||||
///
|
|
||||||
security_code -> Text,
|
|
||||||
///
|
|
||||||
expires_at -> BigInt,
|
|
||||||
///
|
|
||||||
created_at -> BigInt,
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,3 @@
|
||||||
pub mod captcha;
|
|
||||||
pub mod member;
|
pub mod member;
|
||||||
pub mod member_class;
|
pub mod member_class;
|
||||||
pub mod member_level;
|
pub mod member_level;
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
//!
|
//!
|
||||||
//!
|
//!
|
||||||
|
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
use super::super::super::repositories;
|
use super::super::super::repositories;
|
||||||
use beteran_common_rust as bcr;
|
use beteran_common_rust as bcr;
|
||||||
use beteran_protobuf_rust as bpr;
|
use beteran_protobuf_rust as bpr;
|
||||||
|
@ -13,30 +11,34 @@ use diesel::{
|
||||||
use prost::Message;
|
use prost::Message;
|
||||||
|
|
||||||
///
|
///
|
||||||
pub struct Service {
|
pub struct Service<'a> {
|
||||||
connection_broker: nats::asynk::Connection,
|
connection_broker: nats::asynk::Connection,
|
||||||
queue_broker: String,
|
queue_broker: String,
|
||||||
pool: Pool<ConnectionManager<PgConnection>>,
|
pool: Pool<ConnectionManager<PgConnection>>,
|
||||||
member_repository: repositories::member::repository::Repository,
|
member_repository: repositories::member::repository::Repository,
|
||||||
member_site_repository: repositories::member_site::repository::Repository,
|
member_site_repository: repositories::member_site::repository::Repository,
|
||||||
member_session_repository: repositories::member_session::repository::Repository,
|
member_session_repository: repositories::member_session::repository::Repository,
|
||||||
captcha_repository: repositories::captcha::repository::Repository,
|
argon2_config: argon2::Config<'a>,
|
||||||
|
captcha_salt: String,
|
||||||
|
password_salt: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for Service {
|
impl std::fmt::Debug for Service<'_> {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
f.debug_struct("Service of service.member.service.identity")
|
f.debug_struct("Service of service.member.service.identity")
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Service {
|
impl Service<'_> {
|
||||||
///
|
///
|
||||||
pub fn new(
|
pub fn new(
|
||||||
connection_broker: nats::asynk::Connection,
|
connection_broker: nats::asynk::Connection,
|
||||||
queue_broker: String,
|
queue_broker: String,
|
||||||
pool: Pool<ConnectionManager<PgConnection>>,
|
pool: Pool<ConnectionManager<PgConnection>>,
|
||||||
) -> Service {
|
captcha_salt: String,
|
||||||
|
password_salt: String,
|
||||||
|
) -> Service<'static> {
|
||||||
Service {
|
Service {
|
||||||
connection_broker,
|
connection_broker,
|
||||||
queue_broker,
|
queue_broker,
|
||||||
|
@ -44,7 +46,19 @@ impl Service {
|
||||||
member_repository: repositories::member::repository::Repository::new(),
|
member_repository: repositories::member::repository::Repository::new(),
|
||||||
member_site_repository: repositories::member_site::repository::Repository::new(),
|
member_site_repository: repositories::member_site::repository::Repository::new(),
|
||||||
member_session_repository: repositories::member_session::repository::Repository::new(),
|
member_session_repository: repositories::member_session::repository::Repository::new(),
|
||||||
captcha_repository: repositories::captcha::repository::Repository::new(),
|
argon2_config: argon2::Config {
|
||||||
|
variant: argon2::Variant::Argon2i,
|
||||||
|
version: argon2::Version::Version13,
|
||||||
|
mem_cost: 65536,
|
||||||
|
time_cost: 10,
|
||||||
|
lanes: 4,
|
||||||
|
thread_mode: argon2::ThreadMode::Parallel,
|
||||||
|
secret: &[],
|
||||||
|
ad: &[],
|
||||||
|
hash_length: 32,
|
||||||
|
},
|
||||||
|
captcha_salt,
|
||||||
|
password_salt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,23 +302,23 @@ impl Service {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let site_url = match client.site_url {
|
// let site_url = match client.site_url {
|
||||||
Some(site_url) => site_url,
|
// Some(site_url) => site_url,
|
||||||
None => {
|
// None => {
|
||||||
return Err(bcr::error::rpc::Error::InvalidParams(
|
// return Err(bcr::error::rpc::Error::InvalidParams(
|
||||||
bcr::error::rpc::InvalidParams {
|
// bcr::error::rpc::InvalidParams {
|
||||||
message: "invalid site_url information".to_string(),
|
// message: "invalid site_url information".to_string(),
|
||||||
detail: bcr::error::rpc::InvalidParamsDetail {
|
// detail: bcr::error::rpc::InvalidParamsDetail {
|
||||||
location: "request".to_string(),
|
// location: "request".to_string(),
|
||||||
param: "client.site_url".to_string(),
|
// param: "client.site_url".to_string(),
|
||||||
value: "".to_string(),
|
// value: "".to_string(),
|
||||||
error_type: bcr::error::rpc::InvalidParamsType::Required,
|
// error_type: bcr::error::rpc::InvalidParamsType::Required,
|
||||||
message: "".to_string(),
|
// message: "".to_string(),
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
));
|
// ));
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
|
|
||||||
let conn = self.pool.get().map_err(|e| {
|
let conn = self.pool.get().map_err(|e| {
|
||||||
bcr::error::rpc::Error::Server(bcr::error::rpc::Server {
|
bcr::error::rpc::Error::Server(bcr::error::rpc::Server {
|
||||||
|
@ -314,36 +328,37 @@ impl Service {
|
||||||
})
|
})
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
match self
|
// match self
|
||||||
.member_site_repository
|
// .member_site_repository
|
||||||
.select_by_url(&conn, &site_url)
|
// .select_by_url(&conn, &site_url)
|
||||||
.map_err(|e| {
|
// .map_err(|e| {
|
||||||
bcr::error::rpc::Error::Server(bcr::error::rpc::Server {
|
// bcr::error::rpc::Error::Server(bcr::error::rpc::Server {
|
||||||
code: bpr::protobuf::rpc::Error::SERVER_00,
|
// code: bpr::protobuf::rpc::Error::SERVER_00,
|
||||||
message: format!("server {}", e),
|
// message: format!("server {}", e),
|
||||||
data: None,
|
// data: None,
|
||||||
})
|
// })
|
||||||
})? {
|
// })? {
|
||||||
Some(ms) => ms,
|
// Some(ms) => ms,
|
||||||
None => {
|
// None => {
|
||||||
return Err(bcr::error::rpc::Error::InvalidParams(
|
// return Err(bcr::error::rpc::Error::InvalidParams(
|
||||||
bcr::error::rpc::InvalidParams {
|
// bcr::error::rpc::InvalidParams {
|
||||||
message: "invalid site_url information".to_string(),
|
// message: "invalid site_url information".to_string(),
|
||||||
detail: bcr::error::rpc::InvalidParamsDetail {
|
// detail: bcr::error::rpc::InvalidParamsDetail {
|
||||||
location: "request".to_string(),
|
// location: "request".to_string(),
|
||||||
param: "client.site_url".to_string(),
|
// param: "client.site_url".to_string(),
|
||||||
value: "".to_string(),
|
// value: "".to_string(),
|
||||||
error_type: bcr::error::rpc::InvalidParamsType::None,
|
// error_type: bcr::error::rpc::InvalidParamsType::None,
|
||||||
message: "".to_string(),
|
// message: "".to_string(),
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
));
|
// ));
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
|
|
||||||
let mut c = captcha::Captcha::new();
|
let mut c = captcha::Captcha::new();
|
||||||
|
|
||||||
let c = c
|
let c = c
|
||||||
|
.add_chars(5)
|
||||||
.apply_filter(captcha::filters::Noise::new(0.1))
|
.apply_filter(captcha::filters::Noise::new(0.1))
|
||||||
.view(220, 120);
|
.view(220, 120);
|
||||||
|
|
||||||
|
@ -359,30 +374,19 @@ impl Service {
|
||||||
};
|
};
|
||||||
|
|
||||||
let security_code = c.chars_as_string();
|
let security_code = c.chars_as_string();
|
||||||
let expires_at = (chrono::Utc::now() + chrono::Duration::hours(2)).timestamp();
|
let security_code_hash = argon2::hash_encoded(
|
||||||
|
security_code.as_bytes(),
|
||||||
let new_captcha = repositories::captcha::models::NewCaptcha {
|
self.captcha_salt.as_bytes(),
|
||||||
security_code,
|
&self.argon2_config,
|
||||||
expires_at,
|
)
|
||||||
};
|
.unwrap();
|
||||||
|
|
||||||
let inserted_captcha = self
|
|
||||||
.captcha_repository
|
|
||||||
.insert(&conn, &new_captcha)
|
|
||||||
.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,
|
|
||||||
})
|
|
||||||
})?;
|
|
||||||
|
|
||||||
message
|
message
|
||||||
.respond(
|
.respond(
|
||||||
bpr::ss::member::identity::CaptchaResponse {
|
bpr::ss::member::identity::CaptchaResponse {
|
||||||
error: None,
|
error: None,
|
||||||
result: Some(bpr::ss::member::identity::captcha_response::Result {
|
result: Some(bpr::ss::member::identity::captcha_response::Result {
|
||||||
token: inserted_captcha.id.to_string(),
|
security_code_hash,
|
||||||
image: image_as_base64,
|
image: image_as_base64,
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
@ -487,65 +491,28 @@ impl Service {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let captcha_id = uuid::Uuid::from_str(req.token.as_str()).map_err(|e| {
|
let security_code_hash = req.security_code_hash;
|
||||||
bcr::error::rpc::Error::InvalidParams(bcr::error::rpc::InvalidParams {
|
|
||||||
message: "invalid captcha token".to_string(),
|
|
||||||
detail: bcr::error::rpc::InvalidParamsDetail {
|
|
||||||
location: "request".to_string(),
|
|
||||||
param: "token".to_string(),
|
|
||||||
value: "".to_string(),
|
|
||||||
error_type: bcr::error::rpc::InvalidParamsType::None,
|
|
||||||
message: e.to_string(),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
})?;
|
|
||||||
let security_code = req.security_code;
|
let security_code = req.security_code;
|
||||||
let username = req.username;
|
let username = req.username;
|
||||||
let password = req.password;
|
let password = req.password;
|
||||||
|
|
||||||
let captcha = match self
|
let security_code_matches =
|
||||||
.captcha_repository
|
argon2::verify_encoded(security_code_hash.as_str(), security_code.as_bytes()).map_err(
|
||||||
.select(&conn, captcha_id)
|
|e| {
|
||||||
.map_err(|e| {
|
bcr::error::rpc::Error::InvalidParams(bcr::error::rpc::InvalidParams {
|
||||||
bcr::error::rpc::Error::Server(bcr::error::rpc::Server {
|
message: "invalid security_code".to_string(),
|
||||||
code: bpr::protobuf::rpc::Error::SERVER_00,
|
|
||||||
message: format!("server {}", e),
|
|
||||||
data: None,
|
|
||||||
})
|
|
||||||
})? {
|
|
||||||
Some(c) => c,
|
|
||||||
None => {
|
|
||||||
return Err(bcr::error::rpc::Error::InvalidParams(
|
|
||||||
bcr::error::rpc::InvalidParams {
|
|
||||||
message: "invalid captcha token".to_string(),
|
|
||||||
detail: bcr::error::rpc::InvalidParamsDetail {
|
detail: bcr::error::rpc::InvalidParamsDetail {
|
||||||
location: "request".to_string(),
|
location: "request".to_string(),
|
||||||
param: "token".to_string(),
|
param: "security_code".to_string(),
|
||||||
value: "".to_string(),
|
value: security_code.clone(),
|
||||||
error_type: bcr::error::rpc::InvalidParamsType::None,
|
error_type: bcr::error::rpc::InvalidParamsType::None,
|
||||||
message: "".to_string(),
|
message: e.to_string(),
|
||||||
},
|
},
|
||||||
},
|
})
|
||||||
));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if !captcha.expires_at < chrono::Utc::now().timestamp() {
|
|
||||||
return Err(bcr::error::rpc::Error::InvalidParams(
|
|
||||||
bcr::error::rpc::InvalidParams {
|
|
||||||
message: "invalid captcha token".to_string(),
|
|
||||||
detail: bcr::error::rpc::InvalidParamsDetail {
|
|
||||||
location: "request".to_string(),
|
|
||||||
param: "token".to_string(),
|
|
||||||
value: "".to_string(),
|
|
||||||
error_type: bcr::error::rpc::InvalidParamsType::None,
|
|
||||||
message: "captcha token is expired".to_string(),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
));
|
)?;
|
||||||
}
|
|
||||||
|
|
||||||
if !captcha.security_code.eq(&security_code) {
|
if !security_code_matches {
|
||||||
return Err(bcr::error::rpc::Error::InvalidParams(
|
return Err(bcr::error::rpc::Error::InvalidParams(
|
||||||
bcr::error::rpc::InvalidParams {
|
bcr::error::rpc::InvalidParams {
|
||||||
message: "invalid security_code".to_string(),
|
message: "invalid security_code".to_string(),
|
||||||
|
|
Loading…
Reference in New Issue
Block a user