use beteran_common_rust as bcr; use beteran_protobuf_rust as bpr; use prost::Message; /// pub struct Service { connection_broker: nats::asynk::Connection, queue_broker: String, } impl std::fmt::Debug for Service { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { f.debug_struct("beteran-frontend-server-edge::identity::service::Service") .finish() } } impl Service { /// pub fn new(connection_broker: nats::asynk::Connection, queue_broker: String) -> Service { Service { connection_broker, queue_broker, } } pub async fn subscribe(&self) -> std::result::Result<(), std::boxed::Box> { futures::try_join!( self.check_username_for_duplication(), self.check_nickname_for_duplication(), self.captcha(), self.signin(), self.signin_without_security_code(), ) .map(|_| ()) } fn get_client_in_header( &self, message: &nats::asynk::Message, ) -> Result { match &message.headers { Some(headers) => { let client = match headers.get(bpr::c2se::core::network::HEADER_CLIENT) { Some(c) => { let msg = base64::decode(c).map_err(|e| { bcr::error::rpc::Error::Parse(bcr::error::rpc::Parse { message: format!("invalid header: {}", e), }) })?; bpr::models::core::network::Client::decode(msg.as_slice()).map_err(|e| { bcr::error::rpc::Error::Parse(bcr::error::rpc::Parse { message: format!("invalid header: {}", e), }) })? } None => { return Err(bcr::error::rpc::Error::Parse(bcr::error::rpc::Parse { message: "invalid client information".to_string(), })); } }; Ok(client) } None => Err(bcr::error::rpc::Error::Parse(bcr::error::rpc::Parse { message: "invalid header".to_string(), })), } } async fn check_username_for_duplication(&self) -> Result<(), Box> { let s = self .connection_broker .queue_subscribe( bpr::c2se::frontend::identity::SUBJECT_CHECK_USERNAME_FOR_DUPLICATION, self.queue_broker.as_str(), ) .await?; while let Some(message) = s.next().await { if let Err(e) = async { let client = self.get_client_in_header(&message)?; let req = bpr::c2se::identity::CheckUsernameForDuplicationRequest::decode(message.data.as_slice()) .map_err(|e| { bcr::error::rpc::Error::InvalidRequest(bcr::error::rpc::InvalidRequest { message: format!("invalid request: {}", e), }) })?; let ss_check_username_for_duplication_req = bpr::ss::identity::CheckUsernameForDuplicationRequest { client: Some(client), request: Some( bpr::ss::identity::check_username_for_duplication_request::Request { username: req.username, }, ), }; let ss_check_username_for_duplication_res_msg = self .connection_broker .request( bpr::ss::identity::SUBJECT_CHECK_USERNAME_FOR_DUPLICATION, ss_check_username_for_duplication_req.encode_to_vec(), ) .await .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, }) })?; let ss_check_username_for_duplication_res = bpr::ss::identity::CheckUsernameForDuplicationResponse::decode( ss_check_username_for_duplication_res_msg.data.as_slice(), ) .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, }) })?; if let Some(e) = ss_check_username_for_duplication_res.error { return Err(bcr::error::rpc::Error::Server(bcr::error::rpc::Server { code: bpr::protobuf::rpc::Error::SERVER_00, message: format!("server {}", e), data: None, })); } if let Some(r) = ss_check_username_for_duplication_res.result { message .respond( bpr::c2se::identity::CheckUsernameForDuplicationResponse { error: None, result: Some( bpr::c2se::identity::check_username_for_duplication_response::Result { duplicated: r.duplicated, }, ), } .encode_to_vec(), ) .await .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, }) })?; } Ok::<(), bcr::error::rpc::Error>(()) } .await { message .respond( bpr::c2se::identity::CheckUsernameForDuplicationResponse { error: Some(bpr::protobuf::rpc::Error::from(e)), result: None, } .encode_to_vec(), ) .await?; } } Ok(()) } async fn check_nickname_for_duplication(&self) -> Result<(), Box> { let s = self .connection_broker .queue_subscribe( bpr::c2se::frontend::identity::SUBJECT_CHECK_NICKNAME_FOR_DUPLICATION, self.queue_broker.as_str(), ) .await?; while let Some(message) = s.next().await { if let Err(e) = async { let client = self.get_client_in_header(&message)?; let req = bpr::c2se::identity::CheckNicknameForDuplicationRequest::decode(message.data.as_slice()) .map_err(|e| { bcr::error::rpc::Error::InvalidRequest(bcr::error::rpc::InvalidRequest { message: format!("invalid request: {}", e), }) })?; let ss_check_nickname_for_duplication_req = bpr::ss::identity::CheckNicknameForDuplicationRequest { client: Some(client), request: Some( bpr::ss::identity::check_nickname_for_duplication_request::Request { nickname: req.nickname, }, ), }; let ss_check_nickname_for_duplication_res_msg = self .connection_broker .request( bpr::ss::identity::SUBJECT_CHECK_NICKNAME_FOR_DUPLICATION, ss_check_nickname_for_duplication_req.encode_to_vec(), ) .await .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, }) })?; let ss_check_nickname_for_duplication_res = bpr::ss::identity::CheckNicknameForDuplicationResponse::decode( ss_check_nickname_for_duplication_res_msg.data.as_slice(), ) .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, }) })?; if let Some(e) = ss_check_nickname_for_duplication_res.error { return Err(bcr::error::rpc::Error::Server(bcr::error::rpc::Server { code: bpr::protobuf::rpc::Error::SERVER_00, message: format!("server {}", e), data: None, })); } if let Some(r) = ss_check_nickname_for_duplication_res.result { message .respond( bpr::c2se::identity::CheckNicknameForDuplicationResponse { error: None, result: Some( bpr::c2se::identity::check_nickname_for_duplication_response::Result { duplicated: r.duplicated, }, ), } .encode_to_vec(), ) .await .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, }) })?; } Ok::<(), bcr::error::rpc::Error>(()) } .await { message .respond( bpr::c2se::identity::CheckNicknameForDuplicationResponse { error: Some(bpr::protobuf::rpc::Error::from(e)), result: None, } .encode_to_vec(), ) .await?; } } Ok(()) } async fn captcha(&self) -> Result<(), Box> { let s = self .connection_broker .queue_subscribe( bpr::c2se::frontend::identity::SUBJECT_CAPTCHA, self.queue_broker.as_str(), ) .await?; while let Some(message) = s.next().await { if let Err(e) = async { let client = self.get_client_in_header(&message)?; let _req = bpr::c2se::identity::CaptchaRequest::decode(message.data.as_slice()).map_err(|e| { bcr::error::rpc::Error::InvalidRequest(bcr::error::rpc::InvalidRequest { message: format!("invalid request: {}", e), }) })?; let ss_captcha_req = bpr::ss::identity::CaptchaRequest { client: Some(client), request: Some(bpr::ss::identity::captcha_request::Request {}), }; let ss_captcha_res_msg = self .connection_broker .request( bpr::ss::identity::SUBJECT_CAPTCHA, ss_captcha_req.encode_to_vec(), ) .await .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, }) })?; let ss_captcha_res = bpr::ss::identity::CaptchaResponse::decode( ss_captcha_res_msg.data.as_slice(), ) .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, }) })?; if let Some(e) = ss_captcha_res.error { return Err(bcr::error::rpc::Error::Server(bcr::error::rpc::Server { code: bpr::protobuf::rpc::Error::SERVER_00, message: format!("server {}", e), data: None, })); } if let Some(r) = ss_captcha_res.result { message .respond( bpr::c2se::identity::CaptchaResponse { error: None, result: Some(bpr::c2se::identity::captcha_response::Result { security_code_hash: r.security_code_hash, image: r.image, }), } .encode_to_vec(), ) .await .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, }) })?; } Ok::<(), bcr::error::rpc::Error>(()) } .await { message .respond( bpr::c2se::identity::CaptchaResponse { error: Some(bpr::protobuf::rpc::Error::from(e)), result: None, } .encode_to_vec(), ) .await?; } } Ok(()) } async fn signin(&self) -> Result<(), Box> { let s = self .connection_broker .queue_subscribe( bpr::c2se::frontend::identity::SUBJECT_SIGNIN, self.queue_broker.as_str(), ) .await?; while let Some(message) = s.next().await { if let Err(e) = async { let client = self.get_client_in_header(&message)?; let req = bpr::c2se::identity::SigninRequest::decode(message.data.as_slice()).map_err(|e| { bcr::error::rpc::Error::InvalidRequest(bcr::error::rpc::InvalidRequest { message: format!("invalid request: {}", e), }) })?; let ss_signin_req = bpr::ss::identity::SigninRequest { client: Some(client), request: Some(bpr::ss::identity::signin_request::Request { security_code_hash: req.security_code_hash, security_code: req.security_code, username: req.username, password: req.password, }), }; let ss_signin_res_msg = self .connection_broker .request( bpr::ss::identity::SUBJECT_SIGNIN, ss_signin_req.encode_to_vec(), ) .await .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, }) })?; let ss_signin_res = bpr::ss::identity::SigninResponse::decode( ss_signin_res_msg.data.as_slice(), ) .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, }) })?; if let Some(e) = ss_signin_res.error { return Err(bcr::error::rpc::Error::Server(bcr::error::rpc::Server { code: bpr::protobuf::rpc::Error::SERVER_00, message: format!("server {}", e), data: None, })); } if let Some(r) = ss_signin_res.result { message .respond( bpr::c2se::identity::SigninResponse { error: None, result: Some(bpr::c2se::identity::signin_response::Result { access_token: r.access_token, }), } .encode_to_vec(), ) .await .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, }) })?; } Ok::<(), bcr::error::rpc::Error>(()) } .await { message .respond( bpr::c2se::identity::SigninResponse { error: Some(bpr::protobuf::rpc::Error::from(e)), result: None, } .encode_to_vec(), ) .await?; } } Ok(()) } async fn signin_without_security_code(&self) -> Result<(), Box> { let s = self .connection_broker .queue_subscribe( bpr::c2se::frontend::identity::SUBJECT_SIGNIN_WITHOUT_SECURITY_CODE, self.queue_broker.as_str(), ) .await?; while let Some(message) = s.next().await { if let Err(e) = async { let client = self.get_client_in_header(&message)?; let req = bpr::c2se::identity::SigninWithoutSecurityCodeRequest::decode(message.data.as_slice()) .map_err(|e| { bcr::error::rpc::Error::InvalidRequest(bcr::error::rpc::InvalidRequest { message: format!("invalid request: {}", e), }) })?; let ss_signin_without_security_code_req = bpr::ss::identity::SigninWithoutSecurityCodeRequest { client: Some(client), request: Some( bpr::ss::identity::signin_without_security_code_request::Request { username: req.username, password: req.password, }, ), }; let ss_signin_without_security_code_res_msg = self .connection_broker .request( bpr::ss::identity::SUBJECT_SIGNIN_WITHOUT_SECURITY_CODE, ss_signin_without_security_code_req.encode_to_vec(), ) .await .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, }) })?; let ss_signin_without_security_code_res = bpr::ss::identity::SigninWithoutSecurityCodeResponse::decode( ss_signin_without_security_code_res_msg.data.as_slice(), ) .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, }) })?; if let Some(e) = ss_signin_without_security_code_res.error { return Err(bcr::error::rpc::Error::Server(bcr::error::rpc::Server { code: bpr::protobuf::rpc::Error::SERVER_00, message: format!("server {}", e), data: None, })); } if let Some(r) = ss_signin_without_security_code_res.result { message .respond( bpr::c2se::identity::SigninWithoutSecurityCodeResponse { error: None, result: Some( bpr::c2se::identity::signin_without_security_code_response::Result { access_token: r.access_token, }, ), } .encode_to_vec(), ) .await .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, }) })?; } Ok::<(), bcr::error::rpc::Error>(()) } .await { message .respond( bpr::c2se::identity::SigninWithoutSecurityCodeResponse { error: Some(bpr::protobuf::rpc::Error::from(e)), result: None, } .encode_to_vec(), ) .await?; } } Ok(()) } }