Handle sign in process
This commit is contained in:
parent
c0b5128777
commit
15095dc574
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -2245,7 +2245,9 @@ version = "0.8.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9fde2f6a4bea1d6e007c4ad38c6839fa71cbb63b6dbf5b595aa38dc9b1093c11"
|
checksum = "9fde2f6a4bea1d6e007c4ad38c6839fa71cbb63b6dbf5b595aa38dc9b1093c11"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"rand 0.7.3",
|
||||||
"serde",
|
"serde",
|
||||||
|
"sha1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -139,6 +139,7 @@ pub enum Msg {
|
|||||||
AuthTokenStored,
|
AuthTokenStored,
|
||||||
AuthTokenErased,
|
AuthTokenErased,
|
||||||
SignInRequest,
|
SignInRequest,
|
||||||
|
BindClientRequest,
|
||||||
|
|
||||||
StyledSelectChanged(FieldId, StyledSelectChange),
|
StyledSelectChanged(FieldId, StyledSelectChange),
|
||||||
|
|
||||||
@ -189,11 +190,13 @@ fn update(msg: Msg, model: &mut model::Model, orders: &mut impl Orders<Msg>) {
|
|||||||
}
|
}
|
||||||
match &msg {
|
match &msg {
|
||||||
Msg::AuthTokenStored => {
|
Msg::AuthTokenStored => {
|
||||||
seed::push_route(vec!["/dashboard"]);
|
seed::push_route(vec!["dashboard"]);
|
||||||
|
orders.skip().send_msg(Msg::ChangePage(Page::Project));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Msg::AuthTokenErased => {
|
Msg::AuthTokenErased => {
|
||||||
seed::push_route(vec!["/login"]);
|
seed::push_route(vec!["login"]);
|
||||||
|
orders.skip().send_msg(Msg::ChangePage(Page::Login));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Msg::ChangePage(page) => {
|
Msg::ChangePage(page) => {
|
||||||
|
@ -6,12 +6,14 @@ use crate::shared::styled_button::StyledButton;
|
|||||||
use crate::shared::styled_field::StyledField;
|
use crate::shared::styled_field::StyledField;
|
||||||
use crate::shared::styled_form::StyledForm;
|
use crate::shared::styled_form::StyledForm;
|
||||||
use crate::shared::styled_icon::{Icon, StyledIcon};
|
use crate::shared::styled_icon::{Icon, StyledIcon};
|
||||||
use crate::shared::styled_input::StyledInput;
|
use crate::shared::styled_textarea::StyledTextarea;
|
||||||
use crate::shared::{outer_layout, ToNode};
|
use crate::shared::{outer_layout, write_auth_token, ToNode};
|
||||||
use crate::{model, FieldId, LoginFieldId, Msg};
|
use crate::{model, FieldId, LoginFieldId, Msg};
|
||||||
use jirs_data::WsMsg;
|
use jirs_data::WsMsg;
|
||||||
|
use std::str::FromStr;
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
pub fn update(msg: Msg, model: &mut model::Model, _orders: &mut impl Orders<Msg>) {
|
pub fn update(msg: Msg, model: &mut model::Model, orders: &mut impl Orders<Msg>) {
|
||||||
if model.page != Page::Login {
|
if model.page != Page::Login {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -33,15 +35,38 @@ pub fn update(msg: Msg, model: &mut model::Model, _orders: &mut impl Orders<Msg>
|
|||||||
Msg::InputChanged(FieldId::Login(LoginFieldId::Email), value) => {
|
Msg::InputChanged(FieldId::Login(LoginFieldId::Email), value) => {
|
||||||
page.email = value;
|
page.email = value;
|
||||||
}
|
}
|
||||||
|
Msg::InputChanged(FieldId::Login(LoginFieldId::Token), value) => {
|
||||||
|
page.token = value;
|
||||||
|
}
|
||||||
Msg::SignInRequest => {
|
Msg::SignInRequest => {
|
||||||
send_ws_msg(WsMsg::AuthenticateRequest(
|
send_ws_msg(WsMsg::AuthenticateRequest(
|
||||||
page.email.clone(),
|
page.email.clone(),
|
||||||
page.username.clone(),
|
page.username.clone(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
Msg::BindClientRequest => {
|
||||||
|
let bind_token: uuid::Uuid = match Uuid::from_str(page.token.as_str()) {
|
||||||
|
Ok(token) => token,
|
||||||
|
Err(error) => {
|
||||||
|
error!(error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
send_ws_msg(WsMsg::BindTokenCheck(bind_token));
|
||||||
|
}
|
||||||
Msg::WsMsg(WsMsg::AuthenticateSuccess) => {
|
Msg::WsMsg(WsMsg::AuthenticateSuccess) => {
|
||||||
page.login_success = true;
|
page.login_success = true;
|
||||||
}
|
}
|
||||||
|
Msg::WsMsg(WsMsg::BindTokenOk(access_token)) => {
|
||||||
|
match write_auth_token(Some(access_token)) {
|
||||||
|
Ok(msg) => {
|
||||||
|
orders.skip().send_msg(msg);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
error!(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -52,10 +77,11 @@ pub fn view(model: &model::Model) -> Node<Msg> {
|
|||||||
_ => return empty![],
|
_ => return empty![],
|
||||||
};
|
};
|
||||||
|
|
||||||
let username = StyledInput::build(FieldId::Login(LoginFieldId::Username))
|
let username = StyledTextarea::build()
|
||||||
.valid(true)
|
.one_line()
|
||||||
|
.update_on(Ev::Change)
|
||||||
.value(page.username.as_str())
|
.value(page.username.as_str())
|
||||||
.build()
|
.build(FieldId::Login(LoginFieldId::Username))
|
||||||
.into_node();
|
.into_node();
|
||||||
let username_field = StyledField::build()
|
let username_field = StyledField::build()
|
||||||
.label("Username")
|
.label("Username")
|
||||||
@ -63,11 +89,11 @@ pub fn view(model: &model::Model) -> Node<Msg> {
|
|||||||
.build()
|
.build()
|
||||||
.into_node();
|
.into_node();
|
||||||
|
|
||||||
let email = StyledInput::build(FieldId::Login(LoginFieldId::Email))
|
let email = StyledTextarea::build()
|
||||||
.valid(true)
|
.one_line()
|
||||||
|
.update_on(Ev::Change)
|
||||||
.value(page.email.as_str())
|
.value(page.email.as_str())
|
||||||
.input_type("email")
|
.build(FieldId::Login(LoginFieldId::Email))
|
||||||
.build()
|
|
||||||
.into_node();
|
.into_node();
|
||||||
let email_field = StyledField::build()
|
let email_field = StyledField::build()
|
||||||
.label("E-Mail")
|
.label("E-Mail")
|
||||||
@ -100,10 +126,11 @@ pub fn view(model: &model::Model) -> Node<Msg> {
|
|||||||
span!["Why I don't see password?"]
|
span!["Why I don't see password?"]
|
||||||
];
|
];
|
||||||
|
|
||||||
let token = StyledInput::build(FieldId::Login(LoginFieldId::Token))
|
let token = StyledTextarea::build()
|
||||||
.valid(true)
|
.one_line()
|
||||||
|
.update_on(Ev::Input)
|
||||||
.value(page.token.as_str())
|
.value(page.token.as_str())
|
||||||
.build()
|
.build(FieldId::Login(LoginFieldId::Token))
|
||||||
.into_node();
|
.into_node();
|
||||||
let token_field = StyledField::build()
|
let token_field = StyledField::build()
|
||||||
.label("Single use token")
|
.label("Single use token")
|
||||||
@ -113,7 +140,7 @@ pub fn view(model: &model::Model) -> Node<Msg> {
|
|||||||
let submit_token = StyledButton::build()
|
let submit_token = StyledButton::build()
|
||||||
.primary()
|
.primary()
|
||||||
.text("Authorize")
|
.text("Authorize")
|
||||||
.on_click(mouse_ev(Ev::Click, |_| Msg::SignInRequest))
|
.on_click(mouse_ev(Ev::Click, |_| Msg::BindClientRequest))
|
||||||
.build()
|
.build()
|
||||||
.into_node();
|
.into_node();
|
||||||
let submit_token_field = StyledField::build().input(submit_token).build().into_node();
|
let submit_token_field = StyledField::build().input(submit_token).build().into_node();
|
||||||
|
@ -232,6 +232,7 @@ pub struct LoginPage {
|
|||||||
pub email: String,
|
pub email: String,
|
||||||
pub token: String,
|
pub token: String,
|
||||||
pub login_success: bool,
|
pub login_success: bool,
|
||||||
|
pub bad_token: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -53,14 +53,6 @@ impl StyledInputBuilder {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn input_type<S>(mut self, input_type: S) -> Self
|
|
||||||
where
|
|
||||||
S: Into<String>,
|
|
||||||
{
|
|
||||||
self.input_type = Some(input_type.into());
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn build(self) -> StyledInput {
|
pub fn build(self) -> StyledInput {
|
||||||
StyledInput {
|
StyledInput {
|
||||||
id: self.id,
|
id: self.id,
|
||||||
|
@ -40,6 +40,11 @@ pub struct StyledTextareaBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl StyledTextareaBuilder {
|
impl StyledTextareaBuilder {
|
||||||
|
#[inline]
|
||||||
|
pub fn one_line(self) -> Self {
|
||||||
|
self.disable_auto_resize().height(39).max_height(39)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn height(mut self, height: usize) -> Self {
|
pub fn height(mut self, height: usize) -> Self {
|
||||||
self.height = Some(height);
|
self.height = Some(height);
|
||||||
@ -162,12 +167,12 @@ pub fn render(values: StyledTextarea) -> Node<Msg> {
|
|||||||
Msg::NoOp
|
Msg::NoOp
|
||||||
});
|
});
|
||||||
handlers.push(resize_handler);
|
handlers.push(resize_handler);
|
||||||
let text_input_handler = input_ev(update_event, move |value| Msg::InputChanged(id, value));
|
let text_input_handler = ev(update_event, move |event| {
|
||||||
|
let target = event.target().unwrap();
|
||||||
|
let text = seed::to_textarea(&target).value();
|
||||||
|
Msg::InputChanged(id, text)
|
||||||
|
});
|
||||||
handlers.push(text_input_handler);
|
handlers.push(text_input_handler);
|
||||||
handlers.push(keyboard_ev(Ev::Input, |ev| {
|
|
||||||
ev.stop_propagation();
|
|
||||||
Msg::NoOp
|
|
||||||
}));
|
|
||||||
|
|
||||||
class_list.push("textAreaInput".to_string());
|
class_list.push("textAreaInput".to_string());
|
||||||
|
|
||||||
|
@ -474,6 +474,9 @@ pub enum WsMsg {
|
|||||||
AuthorizeExpired,
|
AuthorizeExpired,
|
||||||
AuthenticateRequest(EmailString, UsernameString),
|
AuthenticateRequest(EmailString, UsernameString),
|
||||||
AuthenticateSuccess,
|
AuthenticateSuccess,
|
||||||
|
BindTokenCheck(Uuid),
|
||||||
|
BindTokenBad,
|
||||||
|
BindTokenOk(Uuid),
|
||||||
|
|
||||||
// project page
|
// project page
|
||||||
ProjectRequest,
|
ProjectRequest,
|
||||||
|
@ -32,7 +32,7 @@ bincode = "1.2.1"
|
|||||||
time = { version = "0.1" }
|
time = { version = "0.1" }
|
||||||
url = { version = "2.1.0" }
|
url = { version = "2.1.0" }
|
||||||
percent-encoding = { version = "2.1.0" }
|
percent-encoding = { version = "2.1.0" }
|
||||||
uuid = { version = ">=0.7.0, <0.9.0", features = ["serde"] }
|
uuid = { version = ">=0.7.0, <0.9.0", features = ["serde", "v4", "v5"] }
|
||||||
ipnetwork = { version = ">=0.12.2, <0.17.0" }
|
ipnetwork = { version = ">=0.12.2, <0.17.0" }
|
||||||
num-bigint = { version = ">=0.1.41, <0.3" }
|
num-bigint = { version = ">=0.1.41, <0.3" }
|
||||||
num-traits = { version = "0.2" }
|
num-traits = { version = "0.2" }
|
||||||
|
@ -1,10 +1,19 @@
|
|||||||
insert into projects (name) values ('initial'), ('second'), ('third');
|
insert into projects (name) values ('initial'), ('second'), ('third');
|
||||||
insert into users (project_id, email, name, avatar_url) values (
|
insert into users (project_id, email, name, avatar_url) values (
|
||||||
1, 'john@example.com', 'John Doe', 'http://cdn.onlinewebfonts.com/svg/img_553934.png
|
1,
|
||||||
|
'john@example.com',
|
||||||
|
'John Doe',
|
||||||
|
'http://cdn.onlinewebfonts.com/svg/img_553934.png'
|
||||||
), (
|
), (
|
||||||
1, 'kate@exampe.com', 'Kate Snow', 'http://www.asthmamd.org/images/icon_user_6.png
|
1,
|
||||||
|
'kate@exampe.com',
|
||||||
|
'Kate Snow',
|
||||||
|
'http://www.asthmamd.org/images/icon_user_6.png'
|
||||||
), (
|
), (
|
||||||
1, 'mike@example.com', 'Mike Keningham', 'https://cdn0.iconfinder.com/data/icons/user-pictures/100/matureman1-512.png'
|
1,
|
||||||
|
'mike@example.com',
|
||||||
|
'Mike Keningham',
|
||||||
|
'https://cdn0.iconfinder.com/data/icons/user-pictures/100/matureman1-512.png'
|
||||||
);
|
);
|
||||||
insert into tokens (user_id, access_token, refresh_token) values (1, uuid_generate_v4(), uuid_generate_v4() );
|
insert into tokens (user_id, access_token, refresh_token) values (1, uuid_generate_v4(), uuid_generate_v4() );
|
||||||
insert into issues(
|
insert into issues(
|
||||||
|
@ -7,6 +7,7 @@ use jirs_data::UserId;
|
|||||||
|
|
||||||
use crate::db::DbExecutor;
|
use crate::db::DbExecutor;
|
||||||
use crate::errors::ServiceErrors;
|
use crate::errors::ServiceErrors;
|
||||||
|
use crate::models::{Token, TokenForm};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
pub struct FindBindToken {
|
pub struct FindBindToken {
|
||||||
@ -28,11 +29,17 @@ impl Handler<FindBindToken> for DbExecutor {
|
|||||||
.map_err(|_| ServiceErrors::DatabaseConnectionLost)?;
|
.map_err(|_| ServiceErrors::DatabaseConnectionLost)?;
|
||||||
|
|
||||||
let token: crate::models::Token = tokens
|
let token: crate::models::Token = tokens
|
||||||
.filter(bind_token.eq(msg.token))
|
.filter(bind_token.eq(Some(msg.token)))
|
||||||
.first(conn)
|
.first(conn)
|
||||||
.map_err(|_e| {
|
.map_err(|_e| ServiceErrors::RecordNotFound(format!("token for {}", msg.token)))?;
|
||||||
ServiceErrors::RecordNotFound(format!("token for {}", msg.access_token))
|
|
||||||
})?;
|
let erase_value: Option<Uuid> = None;
|
||||||
|
diesel::update(tokens.find(token.id))
|
||||||
|
.set(bind_token.eq(erase_value))
|
||||||
|
.execute(conn)
|
||||||
|
.map_err(|_| ServiceErrors::DatabaseConnectionLost)?;
|
||||||
|
|
||||||
|
Ok(token)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,10 +56,26 @@ impl Handler<CreateBindToken> for DbExecutor {
|
|||||||
type Result = Result<crate::models::Token, ServiceErrors>;
|
type Result = Result<crate::models::Token, ServiceErrors>;
|
||||||
|
|
||||||
fn handle(&mut self, msg: CreateBindToken, _: &mut Self::Context) -> Self::Result {
|
fn handle(&mut self, msg: CreateBindToken, _: &mut Self::Context) -> Self::Result {
|
||||||
use crate::schema::tokens::dsl::{access_token, tokens};
|
use crate::schema::tokens::dsl::tokens;
|
||||||
let conn = &self
|
let conn = &self
|
||||||
.0
|
.0
|
||||||
.get()
|
.get()
|
||||||
.map_err(|_| ServiceErrors::DatabaseConnectionLost)?;
|
.map_err(|_| ServiceErrors::DatabaseConnectionLost)?;
|
||||||
|
|
||||||
|
let access_token = Uuid::new_v4();
|
||||||
|
let refresh_token = Uuid::new_v4();
|
||||||
|
let bind_token = Some(Uuid::new_v4());
|
||||||
|
|
||||||
|
let form = TokenForm {
|
||||||
|
user_id: msg.user_id,
|
||||||
|
access_token,
|
||||||
|
refresh_token,
|
||||||
|
bind_token,
|
||||||
|
};
|
||||||
|
let row: Token = diesel::insert_into(tokens)
|
||||||
|
.values(form)
|
||||||
|
.get_result(conn)
|
||||||
|
.map_err(|_| ServiceErrors::RecordNotFound("issue comments".to_string()))?;
|
||||||
|
Ok(row)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ use actix::{Handler, Message};
|
|||||||
use diesel::prelude::*;
|
use diesel::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
pub struct FindUser {
|
pub struct FindUser {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub email: String,
|
pub email: String,
|
||||||
@ -30,7 +30,9 @@ impl Handler<FindUser> for DbExecutor {
|
|||||||
.filter(email.eq(msg.email.as_str()))
|
.filter(email.eq(msg.email.as_str()))
|
||||||
.filter(name.eq(msg.name.as_str()))
|
.filter(name.eq(msg.name.as_str()))
|
||||||
.first(conn)
|
.first(conn)
|
||||||
.map_err(|_| ServiceErrors::RecordNotFound("project users".to_string()))?;
|
.map_err(|_| {
|
||||||
|
ServiceErrors::RecordNotFound(format!("user {} {}", msg.name, msg.email))
|
||||||
|
})?;
|
||||||
Ok(row)
|
Ok(row)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -236,4 +236,5 @@ pub struct TokenForm {
|
|||||||
pub user_id: i32,
|
pub user_id: i32,
|
||||||
pub access_token: Uuid,
|
pub access_token: Uuid,
|
||||||
pub refresh_token: Uuid,
|
pub refresh_token: Uuid,
|
||||||
|
pub bind_token: Option<Uuid>,
|
||||||
}
|
}
|
||||||
|
35
jirs-server/src/ws/auth.rs
Normal file
35
jirs-server/src/ws/auth.rs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
use crate::db::tokens::CreateBindToken;
|
||||||
|
use crate::db::users::FindUser;
|
||||||
|
use crate::db::DbExecutor;
|
||||||
|
use crate::ws::WsResult;
|
||||||
|
use actix::Addr;
|
||||||
|
use actix_web::web::Data;
|
||||||
|
use jirs_data::WsMsg;
|
||||||
|
|
||||||
|
pub async fn authenticate(db: &Data<Addr<DbExecutor>>, name: String, email: String) -> WsResult {
|
||||||
|
// TODO check attempt number, allow only 5 times per day
|
||||||
|
let user = match db.send(FindUser { name, email }).await {
|
||||||
|
Ok(Ok(user)) => user,
|
||||||
|
Ok(Err(e)) => {
|
||||||
|
error!("{:?}", e);
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
error!("{:?}", e);
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let _token = match db.send(CreateBindToken { user_id: user.id }).await {
|
||||||
|
Ok(Ok(token)) => token,
|
||||||
|
Ok(Err(e)) => {
|
||||||
|
error!("{:?}", e);
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
error!("{:?}", e);
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// TODO send email somehow
|
||||||
|
Ok(Some(WsMsg::AuthenticateSuccess))
|
||||||
|
}
|
@ -6,8 +6,10 @@ use actix_web_actors::ws;
|
|||||||
use jirs_data::WsMsg;
|
use jirs_data::WsMsg;
|
||||||
|
|
||||||
use crate::db::authorize_user::AuthorizeUser;
|
use crate::db::authorize_user::AuthorizeUser;
|
||||||
|
use crate::db::tokens::FindBindToken;
|
||||||
use crate::db::DbExecutor;
|
use crate::db::DbExecutor;
|
||||||
|
|
||||||
|
pub mod auth;
|
||||||
pub mod comments;
|
pub mod comments;
|
||||||
pub mod issues;
|
pub mod issues;
|
||||||
pub mod projects;
|
pub mod projects;
|
||||||
@ -82,9 +84,10 @@ impl WebSocketActor {
|
|||||||
))?,
|
))?,
|
||||||
|
|
||||||
// auth
|
// auth
|
||||||
WsMsg::AuthorizeRequest(uuid) => block_on(self.authorize(uuid))?,
|
WsMsg::AuthorizeRequest(uuid) => block_on(self.check_auth_token(uuid))?,
|
||||||
|
WsMsg::BindTokenCheck(uuid) => block_on(self.check_bind_token(uuid))?,
|
||||||
WsMsg::AuthenticateRequest(email, name) => {
|
WsMsg::AuthenticateRequest(email, name) => {
|
||||||
block_on(users::authenticate(&self.db, name, email))?
|
block_on(auth::authenticate(&self.db, name, email))?
|
||||||
}
|
}
|
||||||
|
|
||||||
// users
|
// users
|
||||||
@ -129,7 +132,7 @@ impl WebSocketActor {
|
|||||||
Ok(msg)
|
Ok(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn authorize(&mut self, token: uuid::Uuid) -> WsResult {
|
async fn check_auth_token(&mut self, token: uuid::Uuid) -> WsResult {
|
||||||
let m = match self
|
let m = match self
|
||||||
.db
|
.db
|
||||||
.send(AuthorizeUser {
|
.send(AuthorizeUser {
|
||||||
@ -149,6 +152,16 @@ impl WebSocketActor {
|
|||||||
};
|
};
|
||||||
Ok(m)
|
Ok(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn check_bind_token(&mut self, bind_token: uuid::Uuid) -> WsResult {
|
||||||
|
let token: crate::models::Token =
|
||||||
|
match self.db.send(FindBindToken { token: bind_token }).await {
|
||||||
|
Ok(Ok(token)) => token,
|
||||||
|
Ok(Err(_)) => return Ok(Some(WsMsg::BindTokenBad)),
|
||||||
|
_ => return Ok(None),
|
||||||
|
};
|
||||||
|
Ok(Some(WsMsg::BindTokenOk(token.access_token)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for WebSocketActor {
|
impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for WebSocketActor {
|
||||||
|
@ -3,27 +3,10 @@ use actix_web::web::Data;
|
|||||||
|
|
||||||
use jirs_data::WsMsg;
|
use jirs_data::WsMsg;
|
||||||
|
|
||||||
use crate::db::users::{FindUser, LoadProjectUsers};
|
use crate::db::users::LoadProjectUsers;
|
||||||
use crate::db::DbExecutor;
|
use crate::db::DbExecutor;
|
||||||
use crate::ws::{current_user, WsResult};
|
use crate::ws::{current_user, WsResult};
|
||||||
|
|
||||||
pub async fn authenticate(db: &Data<Addr<DbExecutor>>, name: String, email: String) -> WsResult {
|
|
||||||
// TODO check attempt number, allow only 5 times per day
|
|
||||||
let _user = match db.send(FindUser { name, email }).await {
|
|
||||||
Ok(Ok(user)) => user,
|
|
||||||
Ok(Err(e)) => {
|
|
||||||
error!("{:?}", e);
|
|
||||||
return Ok(None);
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
error!("{:?}", e);
|
|
||||||
return Ok(None);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// TODO send email somehow
|
|
||||||
Ok(Some(WsMsg::AuthenticateSuccess))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn load_project_users(
|
pub async fn load_project_users(
|
||||||
db: &Data<Addr<DbExecutor>>,
|
db: &Data<Addr<DbExecutor>>,
|
||||||
user: &Option<jirs_data::User>,
|
user: &Option<jirs_data::User>,
|
||||||
|
Loading…
Reference in New Issue
Block a user