Additional invitation stuff
This commit is contained in:
parent
219b4d3640
commit
80fb8f5466
@ -1,23 +1,24 @@
|
|||||||
use actix::Addr;
|
use actix::AsyncContext;
|
||||||
use actix_web::web::Data;
|
use futures::executor::block_on;
|
||||||
|
|
||||||
use jirs_data::WsMsg;
|
use jirs_data::{Token, WsMsg};
|
||||||
|
|
||||||
use crate::db::tokens::CreateBindToken;
|
use crate::db::authorize_user::AuthorizeUser;
|
||||||
|
use crate::db::tokens::{CreateBindToken, FindBindToken};
|
||||||
use crate::db::users::FindUser;
|
use crate::db::users::FindUser;
|
||||||
use crate::db::DbExecutor;
|
|
||||||
use crate::mail::welcome::Welcome;
|
use crate::mail::welcome::Welcome;
|
||||||
use crate::mail::MailExecutor;
|
use crate::ws::{WebSocketActor, WsHandler, WsResult};
|
||||||
use crate::ws::WsResult;
|
|
||||||
|
|
||||||
pub async fn authenticate(
|
pub struct Authenticate {
|
||||||
db: &Data<Addr<DbExecutor>>,
|
pub name: String,
|
||||||
mail: &Data<Addr<MailExecutor>>,
|
pub email: String,
|
||||||
name: String,
|
}
|
||||||
email: String,
|
|
||||||
) -> WsResult {
|
impl WsHandler<Authenticate> for WebSocketActor {
|
||||||
|
fn handle_msg(&mut self, msg: Authenticate, _ctx: &mut Self::Context) -> WsResult {
|
||||||
|
let Authenticate { name, email } = msg;
|
||||||
// TODO check attempt number, allow only 5 times per day
|
// TODO check attempt number, allow only 5 times per day
|
||||||
let user = match db.send(FindUser { name, email }).await {
|
let user = match block_on(self.db.send(FindUser { name, email })) {
|
||||||
Ok(Ok(user)) => user,
|
Ok(Ok(user)) => user,
|
||||||
Ok(Err(e)) => {
|
Ok(Err(e)) => {
|
||||||
error!("{:?}", e);
|
error!("{:?}", e);
|
||||||
@ -28,7 +29,7 @@ pub async fn authenticate(
|
|||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let token = match db.send(CreateBindToken { user_id: user.id }).await {
|
let token = match block_on(self.db.send(CreateBindToken { user_id: user.id })) {
|
||||||
Ok(Ok(token)) => token,
|
Ok(Ok(token)) => token,
|
||||||
Ok(Err(e)) => {
|
Ok(Err(e)) => {
|
||||||
error!("{:?}", e);
|
error!("{:?}", e);
|
||||||
@ -40,13 +41,10 @@ pub async fn authenticate(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
if let Some(bind_token) = token.bind_token.as_ref().cloned() {
|
if let Some(bind_token) = token.bind_token.as_ref().cloned() {
|
||||||
match mail
|
match block_on(self.mail.send(Welcome {
|
||||||
.send(Welcome {
|
|
||||||
bind_token,
|
bind_token,
|
||||||
email: user.email.clone(),
|
email: user.email.clone(),
|
||||||
})
|
})) {
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(Ok(_)) => (),
|
Ok(Ok(_)) => (),
|
||||||
Ok(Err(e)) => {
|
Ok(Err(e)) => {
|
||||||
error!("{}", e);
|
error!("{}", e);
|
||||||
@ -60,3 +58,44 @@ pub async fn authenticate(
|
|||||||
}
|
}
|
||||||
Ok(Some(WsMsg::AuthenticateSuccess))
|
Ok(Some(WsMsg::AuthenticateSuccess))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct CheckAuthToken {
|
||||||
|
pub token: uuid::Uuid,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WsHandler<CheckAuthToken> for WebSocketActor {
|
||||||
|
fn handle_msg(&mut self, msg: CheckAuthToken, ctx: &mut Self::Context) -> WsResult {
|
||||||
|
let user: jirs_data::User = match block_on(self.db.send(AuthorizeUser {
|
||||||
|
access_token: msg.token,
|
||||||
|
})) {
|
||||||
|
Ok(Ok(u)) => u.into(),
|
||||||
|
Ok(Err(_)) => {
|
||||||
|
return Ok(Some(WsMsg::AuthorizeLoaded(Err(
|
||||||
|
"Invalid auth token".to_string()
|
||||||
|
))))
|
||||||
|
}
|
||||||
|
_ => return Ok(Some(WsMsg::AuthorizeExpired)),
|
||||||
|
};
|
||||||
|
self.current_user = Some(user.clone());
|
||||||
|
block_on(self.join_channel(ctx.address().recipient()));
|
||||||
|
Ok(Some(WsMsg::AuthorizeLoaded(Ok(user))))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct CheckBindToken {
|
||||||
|
pub bind_token: uuid::Uuid,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WsHandler<CheckBindToken> for WebSocketActor {
|
||||||
|
fn handle_msg(&mut self, msg: CheckBindToken, _ctx: &mut Self::Context) -> WsResult {
|
||||||
|
let token: Token = match block_on(self.db.send(FindBindToken {
|
||||||
|
token: msg.bind_token,
|
||||||
|
})) {
|
||||||
|
Ok(Ok(token)) => token,
|
||||||
|
Ok(Err(_)) => return Ok(Some(WsMsg::BindTokenBad)),
|
||||||
|
_ => return Ok(None),
|
||||||
|
};
|
||||||
|
Ok(Some(WsMsg::BindTokenOk(token.access_token)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,98 +1,98 @@
|
|||||||
use actix::Addr;
|
use actix::Addr;
|
||||||
use actix_web::web::Data;
|
use actix_web::web::Data;
|
||||||
|
use futures::executor::block_on;
|
||||||
|
|
||||||
use jirs_data::{CommentId, CreateCommentPayload, IssueId, UpdateCommentPayload, WsMsg};
|
use jirs_data::{CommentId, CreateCommentPayload, IssueId, UpdateCommentPayload, WsMsg};
|
||||||
|
|
||||||
use crate::db::comments::LoadIssueComments;
|
|
||||||
use crate::db::DbExecutor;
|
use crate::db::DbExecutor;
|
||||||
use crate::ws::{current_user, WsResult};
|
use crate::ws::{current_user, WebSocketActor, WsHandler, WsResult};
|
||||||
|
|
||||||
pub async fn load_issues(
|
pub struct LoadIssueComments {
|
||||||
db: &Data<Addr<DbExecutor>>,
|
pub issue_id: IssueId,
|
||||||
user: &Option<jirs_data::User>,
|
}
|
||||||
issue_id: IssueId,
|
|
||||||
) -> WsResult {
|
impl WsHandler<LoadIssueComments> for WebSocketActor {
|
||||||
current_user(user)?;
|
fn handle_msg(&mut self, msg: LoadIssueComments, _ctx: Self::Context) -> WsResult {
|
||||||
let comments = match db.send(LoadIssueComments { issue_id }).await {
|
self.require_user()?;
|
||||||
|
|
||||||
|
let comments = match block_on(self.db.send(crate::db::comments::LoadIssueComments {
|
||||||
|
issue_id: msg.issue_id,
|
||||||
|
})) {
|
||||||
Ok(Ok(comments)) => comments.into_iter().map(|c| c.into()).collect(),
|
Ok(Ok(comments)) => comments.into_iter().map(|c| c.into()).collect(),
|
||||||
_ => return Ok(None),
|
_ => return Ok(None),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Some(WsMsg::IssueCommentsLoaded(comments)))
|
Ok(Some(WsMsg::IssueCommentsLoaded(comments)))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn create_comment(
|
impl WsHandler<CreateCommentPayload> for WebSocketActor {
|
||||||
db: &Data<Addr<DbExecutor>>,
|
fn handle_msg(&mut self, mut msg: CreateCommentPayload, _ctx: Self::Context) -> WsResult {
|
||||||
user: &Option<jirs_data::User>,
|
|
||||||
mut payload: CreateCommentPayload,
|
|
||||||
) -> WsResult {
|
|
||||||
use crate::db::comments::CreateComment;
|
use crate::db::comments::CreateComment;
|
||||||
|
|
||||||
let user_id = current_user(user)?.id;
|
let user_id = self.require_user()?.id;
|
||||||
if payload.user_id.is_none() {
|
if msg.user_id.is_none() {
|
||||||
payload.user_id = Some(user_id);
|
msg.user_id = Some(user_id);
|
||||||
}
|
}
|
||||||
let issue_id = payload.issue_id;
|
let issue_id = msg.issue_id;
|
||||||
match db
|
match block_on(self.db.send(CreateComment {
|
||||||
.send(CreateComment {
|
|
||||||
user_id,
|
user_id,
|
||||||
issue_id,
|
issue_id,
|
||||||
body: payload.body,
|
body: msg.body,
|
||||||
})
|
})) {
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(Ok(_)) => (),
|
Ok(Ok(_)) => (),
|
||||||
_ => return Ok(None),
|
_ => return Ok(None),
|
||||||
};
|
};
|
||||||
load_issues(db, user, issue_id).await
|
self.handle_msg(LoadIssueComments { issue_id })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_comment(
|
impl WsHandler<UpdateCommentPayload> for WebSocketActor {
|
||||||
db: &Data<Addr<DbExecutor>>,
|
fn handle_msg(&mut self, msg: UpdateCommentPayload, _ctx: Self::Context) -> WsResult {
|
||||||
user: &Option<jirs_data::User>,
|
|
||||||
payload: UpdateCommentPayload,
|
|
||||||
) -> WsResult {
|
|
||||||
use crate::db::comments::UpdateComment;
|
use crate::db::comments::UpdateComment;
|
||||||
|
|
||||||
info!("{:?}", payload);
|
info!("{:?}", msg);
|
||||||
let user_id = current_user(user)?.id;
|
let user_id = self.require_user()?.id;
|
||||||
|
|
||||||
let UpdateCommentPayload {
|
let UpdateCommentPayload {
|
||||||
id: comment_id,
|
id: comment_id,
|
||||||
body,
|
body,
|
||||||
} = payload;
|
} = msg;
|
||||||
|
|
||||||
let issue_id = match db
|
let issue_id = match block_on(self.db.send(UpdateComment {
|
||||||
.send(UpdateComment {
|
|
||||||
comment_id,
|
comment_id,
|
||||||
user_id,
|
user_id,
|
||||||
body,
|
body,
|
||||||
})
|
})) {
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(Ok(comment)) => comment.issue_id,
|
Ok(Ok(comment)) => comment.issue_id,
|
||||||
_ => return Ok(None),
|
_ => return Ok(None),
|
||||||
};
|
};
|
||||||
load_issues(db, user, issue_id).await
|
if let Some(v) = self.handle_msg(LoadIssueComments { issue_id })? {
|
||||||
|
self.broadcast(&v);
|
||||||
|
}
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_comment(
|
pub struct DeleteComment {
|
||||||
db: &Data<Addr<DbExecutor>>,
|
pub comment_id: CommentId,
|
||||||
user: &Option<jirs_data::User>,
|
}
|
||||||
comment_id: CommentId,
|
|
||||||
) -> WsResult {
|
impl WsHandler<DeleteComment> for WebSocketActor {
|
||||||
|
fn handle_msg(&mut self, msg: DeleteComment, _ctx: Self::Context) -> WsResult {
|
||||||
use crate::db::comments::DeleteComment;
|
use crate::db::comments::DeleteComment;
|
||||||
|
|
||||||
let user_id = current_user(user)?.id;
|
let user_id = self.require_user()?.id;
|
||||||
|
|
||||||
let msg = DeleteComment {
|
let m = DeleteComment {
|
||||||
comment_id,
|
comment_id: msg.comment_id,
|
||||||
user_id,
|
user_id,
|
||||||
};
|
};
|
||||||
match db.send(msg).await {
|
match block_on(self.db.send(m)) {
|
||||||
Ok(Ok(_)) => (),
|
Ok(Ok(_)) => (),
|
||||||
_ => return Ok(None),
|
_ => return Ok(None),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Some(WsMsg::CommentDeleted(comment_id)))
|
Ok(Some(WsMsg::CommentDeleted(msg.comment_id)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,14 @@
|
|||||||
use actix::{Handler, Message};
|
|
||||||
use futures::executor::block_on;
|
use futures::executor::block_on;
|
||||||
|
|
||||||
use jirs_data::{EmailString, InvitationId, UsernameString, WsMsg};
|
use jirs_data::{EmailString, InvitationId, UsernameString, WsMsg};
|
||||||
|
|
||||||
use crate::db::invitations;
|
use crate::db::invitations;
|
||||||
use crate::ws::{WebSocketActor, WsResult};
|
use crate::ws::{WebSocketActor, WsHandler, WsResult};
|
||||||
|
|
||||||
pub struct ListInvitation;
|
pub struct ListInvitation;
|
||||||
|
|
||||||
impl Message for ListInvitation {
|
impl WsHandler<ListInvitation> for WebSocketActor {
|
||||||
type Result = WsResult;
|
fn handle_msg(&mut self, _msg: ListInvitation, _ctx: &mut Self::Context) -> WsResult {
|
||||||
}
|
|
||||||
|
|
||||||
impl Handler<ListInvitation> for WebSocketActor {
|
|
||||||
type Result = WsResult;
|
|
||||||
|
|
||||||
fn handle(&mut self, _msg: ListInvitation, _ctx: &mut Self::Context) -> Self::Result {
|
|
||||||
let user_id = match self.current_user.as_ref().map(|u| u.id) {
|
let user_id = match self.current_user.as_ref().map(|u| u.id) {
|
||||||
Some(id) => id,
|
Some(id) => id,
|
||||||
_ => return Ok(None),
|
_ => return Ok(None),
|
||||||
@ -33,14 +26,8 @@ pub struct CreateInvitation {
|
|||||||
pub name: UsernameString,
|
pub name: UsernameString,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Message for CreateInvitation {
|
impl WsHandler<CreateInvitation> for WebSocketActor {
|
||||||
type Result = WsResult;
|
fn handle_msg(&mut self, msg: CreateInvitation, _ctx: &mut Self::Context) -> WsResult {
|
||||||
}
|
|
||||||
|
|
||||||
impl Handler<CreateInvitation> for WebSocketActor {
|
|
||||||
type Result = WsResult;
|
|
||||||
|
|
||||||
fn handle(&mut self, msg: CreateInvitation, _ctx: &mut Self::Context) -> Self::Result {
|
|
||||||
let (user_id, project_id) = match self.current_user.as_ref().map(|u| (u.id, u.project_id)) {
|
let (user_id, project_id) = match self.current_user.as_ref().map(|u| (u.id, u.project_id)) {
|
||||||
Some(id) => id,
|
Some(id) => id,
|
||||||
_ => return Ok(None),
|
_ => return Ok(None),
|
||||||
@ -63,14 +50,8 @@ pub struct DeleteInvitation {
|
|||||||
pub id: InvitationId,
|
pub id: InvitationId,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Message for DeleteInvitation {
|
impl WsHandler<DeleteInvitation> for WebSocketActor {
|
||||||
type Result = WsResult;
|
fn handle_msg(&mut self, msg: DeleteInvitation, _ctx: &mut Self::Context) -> WsResult {
|
||||||
}
|
|
||||||
|
|
||||||
impl Handler<DeleteInvitation> for WebSocketActor {
|
|
||||||
type Result = WsResult;
|
|
||||||
|
|
||||||
fn handle(&mut self, msg: DeleteInvitation, _ctx: &mut Self::Context) -> Self::Result {
|
|
||||||
self.require_user()?;
|
self.require_user()?;
|
||||||
let DeleteInvitation { id } = msg;
|
let DeleteInvitation { id } = msg;
|
||||||
let res = match block_on(self.db.send(invitations::DeleteInvitation { id })) {
|
let res = match block_on(self.db.send(invitations::DeleteInvitation { id })) {
|
||||||
@ -85,14 +66,8 @@ pub struct RevokeInvitation {
|
|||||||
pub id: InvitationId,
|
pub id: InvitationId,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Message for RevokeInvitation {
|
impl WsHandler<RevokeInvitation> for WebSocketActor {
|
||||||
type Result = WsResult;
|
fn handle_msg(&mut self, msg: RevokeInvitation, _ctx: &mut Self::Context) -> WsResult {
|
||||||
}
|
|
||||||
|
|
||||||
impl Handler<RevokeInvitation> for WebSocketActor {
|
|
||||||
type Result = WsResult;
|
|
||||||
|
|
||||||
fn handle(&mut self, msg: RevokeInvitation, _ctx: &mut Self::Context) -> Self::Result {
|
|
||||||
self.require_user()?;
|
self.require_user()?;
|
||||||
let RevokeInvitation { id } = msg;
|
let RevokeInvitation { id } = msg;
|
||||||
let res = match block_on(self.db.send(invitations::RevokeInvitation { id })) {
|
let res = match block_on(self.db.send(invitations::RevokeInvitation { id })) {
|
||||||
@ -107,14 +82,8 @@ pub struct AcceptInvitation {
|
|||||||
pub id: InvitationId,
|
pub id: InvitationId,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Message for AcceptInvitation {
|
impl WsHandler<AcceptInvitation> for WebSocketActor {
|
||||||
type Result = WsResult;
|
fn handle_msg(&mut self, msg: AcceptInvitation, _ctx: &mut Self::Context) -> WsResult {
|
||||||
}
|
|
||||||
|
|
||||||
impl Handler<AcceptInvitation> for WebSocketActor {
|
|
||||||
type Result = WsResult;
|
|
||||||
|
|
||||||
fn handle(&mut self, msg: AcceptInvitation, _ctx: &mut Self::Context) -> Self::Result {
|
|
||||||
self.require_user()?;
|
self.require_user()?;
|
||||||
let AcceptInvitation { id } = msg;
|
let AcceptInvitation { id } = msg;
|
||||||
let res = match block_on(self.db.send(invitations::AcceptInvitation { id })) {
|
let res = match block_on(self.db.send(invitations::AcceptInvitation { id })) {
|
||||||
|
@ -1,15 +1,12 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use actix::*;
|
|
||||||
use actix_web::web::Data;
|
|
||||||
use futures::executor::block_on;
|
use futures::executor::block_on;
|
||||||
|
|
||||||
use jirs_data::{IssueAssignee, IssueFieldId, PayloadVariant, WsMsg};
|
use jirs_data::{CreateIssuePayload, IssueAssignee, IssueFieldId, IssueId, PayloadVariant, WsMsg};
|
||||||
|
|
||||||
use crate::db::issue_assignees::LoadAssignees;
|
use crate::db::issue_assignees::LoadAssignees;
|
||||||
use crate::db::issues::{LoadProjectIssues, UpdateIssue};
|
use crate::db::issues::{LoadProjectIssues, UpdateIssue};
|
||||||
use crate::db::DbExecutor;
|
use crate::ws::{WebSocketActor, WsHandler, WsResult};
|
||||||
use crate::ws::{current_user, WebSocketActor, WsResult};
|
|
||||||
|
|
||||||
pub struct UpdateIssueHandler {
|
pub struct UpdateIssueHandler {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
@ -17,18 +14,8 @@ pub struct UpdateIssueHandler {
|
|||||||
pub payload: PayloadVariant,
|
pub payload: PayloadVariant,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Message for UpdateIssueHandler {
|
impl WsHandler<UpdateIssueHandler> for WebSocketActor {
|
||||||
type Result = WsResult;
|
fn handle_msg(&mut self, msg: UpdateIssueHandler, _ctx: &mut Self::Context) -> WsResult {
|
||||||
}
|
|
||||||
|
|
||||||
impl Actor for UpdateIssueHandler {
|
|
||||||
type Context = Context<Self>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Handler<UpdateIssueHandler> for WebSocketActor {
|
|
||||||
type Result = WsResult;
|
|
||||||
|
|
||||||
fn handle(&mut self, msg: UpdateIssueHandler, _ctx: &mut Self::Context) -> Self::Result {
|
|
||||||
self.require_user()?;
|
self.require_user()?;
|
||||||
|
|
||||||
let UpdateIssueHandler {
|
let UpdateIssueHandler {
|
||||||
@ -90,134 +77,75 @@ impl Handler<UpdateIssueHandler> for WebSocketActor {
|
|||||||
for assignee in assignees {
|
for assignee in assignees {
|
||||||
issue.user_ids.push(assignee.user_id);
|
issue.user_ids.push(assignee.user_id);
|
||||||
}
|
}
|
||||||
|
self.broadcast(&WsMsg::IssueUpdated(issue));
|
||||||
|
|
||||||
Ok(Some(WsMsg::IssueUpdated(issue)))
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_issue(
|
impl WsHandler<CreateIssuePayload> for WebSocketActor {
|
||||||
db: &Data<Addr<DbExecutor>>,
|
fn handle_msg(&mut self, msg: CreateIssuePayload, _ctx: &mut Self::Context) -> WsResult {
|
||||||
user: &Option<jirs_data::User>,
|
self.require_user()?;
|
||||||
issue_id: i32,
|
|
||||||
issue_field_id: IssueFieldId,
|
|
||||||
payload: PayloadVariant,
|
|
||||||
) -> WsResult {
|
|
||||||
current_user(user)?;
|
|
||||||
|
|
||||||
let mut msg = UpdateIssue::default();
|
|
||||||
msg.issue_id = issue_id;
|
|
||||||
match (issue_field_id, payload) {
|
|
||||||
(IssueFieldId::Type, PayloadVariant::IssueType(t)) => {
|
|
||||||
msg.issue_type = Some(t);
|
|
||||||
}
|
|
||||||
(IssueFieldId::Title, PayloadVariant::String(s)) => {
|
|
||||||
msg.title = Some(s);
|
|
||||||
}
|
|
||||||
(IssueFieldId::Description, PayloadVariant::String(s)) => {
|
|
||||||
msg.description = Some(s);
|
|
||||||
}
|
|
||||||
(IssueFieldId::Status, PayloadVariant::IssueStatus(s)) => {
|
|
||||||
msg.status = Some(s);
|
|
||||||
}
|
|
||||||
(IssueFieldId::ListPosition, PayloadVariant::I32(i)) => {
|
|
||||||
msg.list_position = Some(i);
|
|
||||||
}
|
|
||||||
(IssueFieldId::Assignees, PayloadVariant::VecI32(v)) => {
|
|
||||||
msg.user_ids = Some(v);
|
|
||||||
}
|
|
||||||
(IssueFieldId::Reporter, PayloadVariant::I32(i)) => {
|
|
||||||
msg.reporter_id = Some(i);
|
|
||||||
}
|
|
||||||
(IssueFieldId::Priority, PayloadVariant::IssuePriority(p)) => {
|
|
||||||
msg.priority = Some(p);
|
|
||||||
}
|
|
||||||
(IssueFieldId::Estimate, PayloadVariant::OptionI32(o)) => {
|
|
||||||
msg.estimate = o;
|
|
||||||
}
|
|
||||||
(IssueFieldId::TimeSpend, PayloadVariant::OptionI32(o)) => {
|
|
||||||
msg.time_spent = o;
|
|
||||||
}
|
|
||||||
(IssueFieldId::TimeRemaining, PayloadVariant::OptionI32(o)) => {
|
|
||||||
msg.time_remaining = o;
|
|
||||||
}
|
|
||||||
_ => (),
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut issue: jirs_data::Issue = match db.send(msg).await {
|
|
||||||
Ok(Ok(issue)) => issue.into(),
|
|
||||||
_ => return Ok(None),
|
|
||||||
};
|
|
||||||
|
|
||||||
let assignees = match db.send(LoadAssignees { issue_id: issue.id }).await {
|
|
||||||
Ok(Ok(v)) => v,
|
|
||||||
_ => vec![],
|
|
||||||
};
|
|
||||||
for assignee in assignees {
|
|
||||||
issue.user_ids.push(assignee.user_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Some(WsMsg::IssueUpdated(issue)))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn add_issue(
|
|
||||||
db: &Data<Addr<DbExecutor>>,
|
|
||||||
user: &Option<jirs_data::User>,
|
|
||||||
payload: jirs_data::CreateIssuePayload,
|
|
||||||
) -> WsResult {
|
|
||||||
current_user(user)?;
|
|
||||||
let msg = crate::db::issues::CreateIssue {
|
let msg = crate::db::issues::CreateIssue {
|
||||||
title: payload.title,
|
title: msg.title,
|
||||||
issue_type: payload.issue_type,
|
issue_type: msg.issue_type,
|
||||||
status: payload.status,
|
status: msg.status,
|
||||||
priority: payload.priority,
|
priority: msg.priority,
|
||||||
description: payload.description,
|
description: msg.description,
|
||||||
description_text: payload.description_text,
|
description_text: msg.description_text,
|
||||||
estimate: payload.estimate,
|
estimate: msg.estimate,
|
||||||
time_spent: payload.time_spent,
|
time_spent: msg.time_spent,
|
||||||
time_remaining: payload.time_remaining,
|
time_remaining: msg.time_remaining,
|
||||||
project_id: payload.project_id,
|
project_id: msg.project_id,
|
||||||
reporter_id: payload.reporter_id,
|
reporter_id: msg.reporter_id,
|
||||||
user_ids: payload.user_ids,
|
user_ids: msg.user_ids,
|
||||||
};
|
};
|
||||||
let m = match db.send(msg).await {
|
let m = match block_on(self.db.send(msg)) {
|
||||||
Ok(Ok(issue)) => Some(WsMsg::IssueCreated(issue.into())),
|
Ok(Ok(issue)) => Some(WsMsg::IssueCreated(issue.into())),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
Ok(m)
|
Ok(m)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn delete_issue(
|
pub struct DeleteIssue {
|
||||||
db: &Data<Addr<DbExecutor>>,
|
pub id: IssueId,
|
||||||
user: &Option<jirs_data::User>,
|
}
|
||||||
id: i32,
|
|
||||||
) -> WsResult {
|
impl WsHandler<DeleteIssue> for WebSocketActor {
|
||||||
current_user(user)?;
|
fn handle_msg(&mut self, msg: DeleteIssue, _ctx: &mut Self::Context) -> WsResult {
|
||||||
let m = match db
|
self.require_user()?;
|
||||||
.send(crate::db::issues::DeleteIssue { issue_id: id })
|
let m = match block_on(
|
||||||
.await
|
self.db
|
||||||
{
|
.send(crate::db::issues::DeleteIssue { issue_id: msg.id }),
|
||||||
Ok(Ok(_)) => Some(WsMsg::IssueDeleted(id)),
|
) {
|
||||||
|
Ok(Ok(_)) => Some(WsMsg::IssueDeleted(msg.id)),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
Ok(m)
|
Ok(m)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn load_issues(db: &Data<Addr<DbExecutor>>, user: &Option<jirs_data::User>) -> WsResult {
|
pub struct LoadIssues;
|
||||||
let project_id = current_user(user).map(|u| u.project_id)?;
|
|
||||||
|
|
||||||
let issues: Vec<jirs_data::Issue> = match db.send(LoadProjectIssues { project_id }).await {
|
impl WsHandler<LoadIssues> for WebSocketActor {
|
||||||
|
fn handle_msg(&mut self, _msg: LoadIssues, _ctx: &mut Self::Context) -> WsResult {
|
||||||
|
let project_id = self.require_user()?.project_id;
|
||||||
|
|
||||||
|
let issues: Vec<jirs_data::Issue> =
|
||||||
|
match block_on(self.db.send(LoadProjectIssues { project_id })) {
|
||||||
Ok(Ok(v)) => v.into_iter().map(|i| i.into()).collect(),
|
Ok(Ok(v)) => v.into_iter().map(|i| i.into()).collect(),
|
||||||
_ => return Ok(None),
|
_ => return Ok(None),
|
||||||
};
|
};
|
||||||
let mut issue_map = HashMap::new();
|
let mut issue_map = HashMap::new();
|
||||||
let mut queue = vec![];
|
let mut queue = vec![];
|
||||||
for issue in issues.into_iter() {
|
for issue in issues.into_iter() {
|
||||||
let f = db.send(LoadAssignees { issue_id: issue.id });
|
let f = self.db.send(LoadAssignees { issue_id: issue.id });
|
||||||
queue.push(f);
|
queue.push(f);
|
||||||
issue_map.insert(issue.id, issue);
|
issue_map.insert(issue.id, issue);
|
||||||
}
|
}
|
||||||
for f in queue {
|
for f in queue {
|
||||||
if let Ok(Ok(assignees)) = f.await {
|
if let Ok(Ok(assignees)) = block_on(f) {
|
||||||
for assignee in assignees {
|
for assignee in assignees {
|
||||||
if let Some(issue) = issue_map.get_mut(&assignee.issue_id) {
|
if let Some(issue) = issue_map.get_mut(&assignee.issue_id) {
|
||||||
issue.user_ids.push(assignee.user_id);
|
issue.user_ids.push(assignee.user_id);
|
||||||
@ -232,3 +160,4 @@ pub async fn load_issues(db: &Data<Addr<DbExecutor>>, user: &Option<jirs_data::U
|
|||||||
|
|
||||||
Ok(Some(WsMsg::ProjectIssuesLoaded(issues)))
|
Ok(Some(WsMsg::ProjectIssuesLoaded(issues)))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -1,20 +1,18 @@
|
|||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
use actix::{
|
use actix::{Actor, ActorContext, Addr, Context, Handler, Message, Recipient, StreamHandler};
|
||||||
Actor, ActorContext, Addr, AsyncContext, Context, Handler, Message, Recipient, StreamHandler,
|
|
||||||
};
|
|
||||||
use actix_web::web::Data;
|
use actix_web::web::Data;
|
||||||
use actix_web::{get, web, Error, HttpRequest, HttpResponse};
|
use actix_web::{get, web, Error, HttpRequest, HttpResponse};
|
||||||
use actix_web_actors::ws;
|
use actix_web_actors::ws;
|
||||||
use futures::executor::block_on;
|
use futures::executor::block_on;
|
||||||
use futures::SinkExt;
|
|
||||||
|
|
||||||
use jirs_data::{ProjectId, Token, UserId, WsMsg};
|
use jirs_data::{ProjectId, UserId, WsMsg};
|
||||||
|
|
||||||
use crate::db::authorize_user::AuthorizeUser;
|
|
||||||
use crate::db::tokens::FindBindToken;
|
|
||||||
use crate::db::DbExecutor;
|
use crate::db::DbExecutor;
|
||||||
use crate::mail::MailExecutor;
|
use crate::mail::MailExecutor;
|
||||||
|
use crate::ws::auth::{Authenticate, CheckAuthToken, CheckBindToken};
|
||||||
|
use crate::ws::invitations::*;
|
||||||
|
use crate::ws::issues::UpdateIssueHandler;
|
||||||
|
|
||||||
pub mod auth;
|
pub mod auth;
|
||||||
pub mod comments;
|
pub mod comments;
|
||||||
@ -88,83 +86,69 @@ impl WebSocketActor {
|
|||||||
WsMsg::Pong => Some(WsMsg::Ping),
|
WsMsg::Pong => Some(WsMsg::Ping),
|
||||||
|
|
||||||
// Issues
|
// Issues
|
||||||
WsMsg::IssueUpdateRequest(id, field_id, payload) => match block_on(
|
WsMsg::IssueUpdateRequest(id, field_id, payload) => self.handle_msg(
|
||||||
issues::update_issue(&self.db, &self.current_user, id, field_id, payload),
|
UpdateIssueHandler {
|
||||||
) {
|
id,
|
||||||
Ok(Some(msg)) => {
|
field_id,
|
||||||
self.broadcast(&msg);
|
payload,
|
||||||
None
|
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
},
|
},
|
||||||
WsMsg::IssueCreateRequest(payload) => {
|
ctx,
|
||||||
block_on(issues::add_issue(&self.db, &self.current_user, payload))?
|
)?,
|
||||||
}
|
WsMsg::IssueCreateRequest(payload) => self.handle_msg(payload, ctx)?,
|
||||||
WsMsg::IssueDeleteRequest(id) => {
|
WsMsg::IssueDeleteRequest(id) => self.handle_msg(issues::DeleteIssue { id }, ctx)?,
|
||||||
block_on(issues::delete_issue(&self.db, &self.current_user, id))?
|
WsMsg::ProjectIssuesRequest => self.handle_msg(issues::LoadIssues, ctx)?,
|
||||||
}
|
|
||||||
WsMsg::ProjectIssuesRequest => {
|
|
||||||
block_on(issues::load_issues(&self.db, &self.current_user))?
|
|
||||||
}
|
|
||||||
|
|
||||||
// projects
|
// projects
|
||||||
WsMsg::ProjectRequest => {
|
WsMsg::ProjectRequest => self.handle_msg(projects::CurrentProject, ctx)?,
|
||||||
block_on(projects::current_project(&self.db, &self.current_user))?
|
WsMsg::ProjectUpdateRequest(payload) => self.handle_msg(payload, ctx)?,
|
||||||
}
|
|
||||||
|
|
||||||
WsMsg::ProjectUpdateRequest(payload) => block_on(projects::update_project(
|
|
||||||
&self.db,
|
|
||||||
&self.current_user,
|
|
||||||
payload,
|
|
||||||
))?,
|
|
||||||
|
|
||||||
// auth
|
// auth
|
||||||
WsMsg::AuthorizeRequest(uuid) => block_on(self.check_auth_token(uuid, ctx))?,
|
WsMsg::AuthorizeRequest(uuid) => {
|
||||||
WsMsg::BindTokenCheck(uuid) => block_on(self.check_bind_token(uuid))?,
|
self.handle_msg(CheckAuthToken { token: uuid }, ctx)?
|
||||||
|
}
|
||||||
|
WsMsg::BindTokenCheck(uuid) => {
|
||||||
|
self.handle_msg(CheckBindToken { bind_token: uuid }, ctx)?
|
||||||
|
}
|
||||||
WsMsg::AuthenticateRequest(email, name) => {
|
WsMsg::AuthenticateRequest(email, name) => {
|
||||||
block_on(auth::authenticate(&self.db, &self.mail, name, email))?
|
self.handle_msg(Authenticate { name, email }, ctx)?
|
||||||
}
|
}
|
||||||
|
|
||||||
// register
|
// register
|
||||||
WsMsg::SignUpRequest(email, username) => {
|
WsMsg::SignUpRequest(email, username) => self.handle_msg(
|
||||||
block_on(users::register(&self.db, &self.mail, username, email))?
|
users::Register {
|
||||||
}
|
name: username,
|
||||||
|
email,
|
||||||
|
},
|
||||||
|
ctx,
|
||||||
|
)?,
|
||||||
|
|
||||||
// users
|
// users
|
||||||
WsMsg::ProjectUsersRequest => {
|
WsMsg::ProjectUsersRequest => self.handle_msg(users::LoadProjectUsers, ctx)?,
|
||||||
block_on(users::load_project_users(&self.db, &self.current_user))?
|
|
||||||
}
|
|
||||||
|
|
||||||
// comments
|
// comments
|
||||||
WsMsg::IssueCommentsRequest(issue_id) => block_on(comments::load_issues(
|
WsMsg::IssueCommentsRequest(issue_id) => {
|
||||||
&self.db,
|
self.handle_msg(comments::LoadIssueComments { issue_id }, ctx)?
|
||||||
&self.current_user,
|
}
|
||||||
issue_id,
|
WsMsg::CreateComment(payload) => self.handle_msg(payload, ctx)?,
|
||||||
))?,
|
WsMsg::UpdateComment(payload) => self.handle_msg(payload, ctx)?,
|
||||||
|
WsMsg::CommentDeleteRequest(comment_id) => {
|
||||||
WsMsg::CreateComment(payload) => block_on(comments::create_comment(
|
self.handle_msg(comments::DeleteComment { comment_id }, ctx)?
|
||||||
&self.db,
|
|
||||||
&self.current_user,
|
|
||||||
payload,
|
|
||||||
))?,
|
|
||||||
|
|
||||||
WsMsg::UpdateComment(payload) => match block_on(comments::update_comment(
|
|
||||||
&self.db,
|
|
||||||
&self.current_user,
|
|
||||||
payload,
|
|
||||||
)) {
|
|
||||||
Ok(Some(msg)) => {
|
|
||||||
self.broadcast(&msg);
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
_ => None,
|
|
||||||
},
|
|
||||||
|
|
||||||
WsMsg::CommentDeleteRequest(comment_id) => block_on(comments::delete_comment(
|
// invitations
|
||||||
&self.db,
|
WsMsg::InvitationSendRequest { name, email } => self.handle_msg(
|
||||||
&self.current_user,
|
CreateInvitation {
|
||||||
comment_id,
|
name: name.clone(),
|
||||||
))?,
|
email: email.clone(),
|
||||||
|
},
|
||||||
|
ctx,
|
||||||
|
)?,
|
||||||
|
WsMsg::InvitationListRequest => self.handle_msg(ListInvitation, ctx)?,
|
||||||
|
WsMsg::InvitationAcceptRequest(id) => self.handle_msg(AcceptInvitation { id }, ctx)?,
|
||||||
|
|
||||||
|
WsMsg::InvitationRevokeRequest(id) => self.handle_msg(RevokeInvitation { id }, ctx)?,
|
||||||
|
|
||||||
|
WsMsg::InvitedUsersRequest => None,
|
||||||
|
|
||||||
// else fail
|
// else fail
|
||||||
_ => {
|
_ => {
|
||||||
@ -178,41 +162,6 @@ impl WebSocketActor {
|
|||||||
Ok(msg)
|
Ok(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn check_auth_token(
|
|
||||||
&mut self,
|
|
||||||
token: uuid::Uuid,
|
|
||||||
ctx: &mut <WebSocketActor as Actor>::Context,
|
|
||||||
) -> WsResult {
|
|
||||||
let m = match self
|
|
||||||
.db
|
|
||||||
.send(AuthorizeUser {
|
|
||||||
access_token: token,
|
|
||||||
})
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(Ok(u)) => {
|
|
||||||
let user: jirs_data::User = u.into();
|
|
||||||
self.current_user = Some(user.clone());
|
|
||||||
self.join_channel(ctx.address().recipient()).await;
|
|
||||||
Some(WsMsg::AuthorizeLoaded(Ok(user)))
|
|
||||||
}
|
|
||||||
Ok(Err(_)) => Some(WsMsg::AuthorizeLoaded(
|
|
||||||
Err("Invalid auth token".to_string()),
|
|
||||||
)),
|
|
||||||
_ => Some(WsMsg::AuthorizeExpired),
|
|
||||||
};
|
|
||||||
Ok(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn check_bind_token(&mut self, bind_token: uuid::Uuid) -> WsResult {
|
|
||||||
let token: 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)))
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn join_channel(&self, addr: Recipient<InnerMsg>) {
|
async fn join_channel(&self, addr: Recipient<InnerMsg>) {
|
||||||
info!("joining channel...");
|
info!("joining channel...");
|
||||||
info!(" current user {:?}", self.current_user);
|
info!(" current user {:?}", self.current_user);
|
||||||
@ -267,35 +216,11 @@ impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for WebSocketActor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WebSocketActor {
|
pub trait WsHandler<Message>
|
||||||
fn try_handle_message(
|
|
||||||
&mut self,
|
|
||||||
msg: WsMsg,
|
|
||||||
_ctx: &mut <WebSocketActor as Actor>::Context,
|
|
||||||
) -> WsResult
|
|
||||||
where
|
where
|
||||||
Self: Actor,
|
Self: Actor,
|
||||||
{
|
{
|
||||||
match msg {
|
fn handle_msg(&mut self, msg: Message, _ctx: &mut <Self as Actor>::Context) -> WsResult;
|
||||||
WsMsg::InvitationSendRequest { name, email } => {
|
|
||||||
use invitations::*;
|
|
||||||
|
|
||||||
let m = CreateInvitation {
|
|
||||||
name: name.clone(),
|
|
||||||
email: email.clone(),
|
|
||||||
};
|
|
||||||
// Handler::handle(&mut self, m, _ctx);
|
|
||||||
Ok(None)
|
|
||||||
// Handler::<CreateInvitation>::handle(&mut self, m, _ctx)
|
|
||||||
// <self as Handler<CreateInvitation>>.handle(m, ctx)
|
|
||||||
}
|
|
||||||
// WsMsg::InvitationListRequest => self.handle(ListInvitation, ctx),
|
|
||||||
// WsMsg::InvitationAcceptRequest(id) => Ok(None),
|
|
||||||
// WsMsg::InvitationRevokeRequest(id) => self.handle(RevokeInvitation { id: *id }, ctx),
|
|
||||||
// WsMsg::InvitedUsersRequest => Ok(None),
|
|
||||||
_ => Ok(None),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Message, Debug)]
|
#[derive(Message, Debug)]
|
||||||
|
@ -1,19 +1,17 @@
|
|||||||
use actix::Addr;
|
use futures::executor::block_on;
|
||||||
use actix_web::web::Data;
|
|
||||||
|
|
||||||
use jirs_data::{UpdateProjectPayload, WsMsg};
|
use jirs_data::{UpdateProjectPayload, WsMsg};
|
||||||
|
|
||||||
use crate::db::projects::LoadCurrentProject;
|
use crate::db::projects::LoadCurrentProject;
|
||||||
use crate::db::DbExecutor;
|
use crate::ws::{WebSocketActor, WsHandler, WsResult};
|
||||||
use crate::ws::{current_user, WsResult};
|
|
||||||
|
|
||||||
pub async fn current_project(
|
pub struct CurrentProject;
|
||||||
db: &Data<Addr<DbExecutor>>,
|
|
||||||
user: &Option<jirs_data::User>,
|
|
||||||
) -> WsResult {
|
|
||||||
let project_id = current_user(user).map(|u| u.project_id)?;
|
|
||||||
|
|
||||||
let m = match db.send(LoadCurrentProject { project_id }).await {
|
impl WsHandler<CurrentProject> for WebSocketActor {
|
||||||
|
fn handle_msg(&mut self, _msg: CurrentProject, _ctx: &mut Self::Context) -> WsResult {
|
||||||
|
let project_id = self.require_user()?.project_id;
|
||||||
|
|
||||||
|
let m = match block_on(self.db.send(LoadCurrentProject { project_id })) {
|
||||||
Ok(Ok(project)) => Some(WsMsg::ProjectLoaded(project.into())),
|
Ok(Ok(project)) => Some(WsMsg::ProjectLoaded(project.into())),
|
||||||
Ok(Err(e)) => {
|
Ok(Err(e)) => {
|
||||||
error!("{:?}", e);
|
error!("{:?}", e);
|
||||||
@ -26,25 +24,21 @@ pub async fn current_project(
|
|||||||
};
|
};
|
||||||
Ok(m)
|
Ok(m)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn update_project(
|
impl WsHandler<UpdateProjectPayload> for WebSocketActor {
|
||||||
db: &Data<Addr<DbExecutor>>,
|
fn handle_msg(&mut self, msg: UpdateProjectPayload, _ctx: &mut Self::Context) -> WsResult {
|
||||||
user: &Option<jirs_data::User>,
|
let project_id = self.require_user()?.project_id;
|
||||||
payload: UpdateProjectPayload,
|
let project = match block_on(self.db.send(crate::db::projects::UpdateProject {
|
||||||
) -> WsResult {
|
|
||||||
let project_id = current_user(user).map(|u| u.project_id)?;
|
|
||||||
let project = match db
|
|
||||||
.send(crate::db::projects::UpdateProject {
|
|
||||||
project_id,
|
project_id,
|
||||||
name: payload.name,
|
name: msg.name,
|
||||||
url: payload.url,
|
url: msg.url,
|
||||||
description: payload.description,
|
description: msg.description,
|
||||||
category: payload.category,
|
category: msg.category,
|
||||||
})
|
})) {
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(Ok(project)) => project,
|
Ok(Ok(project)) => project,
|
||||||
_ => return Ok(None),
|
_ => return Ok(None),
|
||||||
};
|
};
|
||||||
Ok(Some(WsMsg::ProjectLoaded(project.into())))
|
Ok(Some(WsMsg::ProjectLoaded(project.into())))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -1,20 +1,19 @@
|
|||||||
use actix::Addr;
|
use futures::executor::block_on;
|
||||||
use actix_web::web::Data;
|
|
||||||
|
|
||||||
use jirs_data::WsMsg;
|
use jirs_data::WsMsg;
|
||||||
|
|
||||||
use crate::db::users::{LoadProjectUsers, Register};
|
use crate::db::users::Register as DbRegister;
|
||||||
use crate::db::DbExecutor;
|
use crate::ws::auth::Authenticate;
|
||||||
use crate::mail::MailExecutor;
|
use crate::ws::{current_user, WebSocketActor, WsHandler, WsResult};
|
||||||
use crate::ws::auth::authenticate;
|
|
||||||
use crate::ws::{current_user, WsResult};
|
|
||||||
|
|
||||||
pub async fn load_project_users(
|
pub struct LoadProjectUsers;
|
||||||
db: &Data<Addr<DbExecutor>>,
|
|
||||||
user: &Option<jirs_data::User>,
|
impl WsHandler<LoadProjectUsers> for WebSocketActor {
|
||||||
) -> WsResult {
|
fn handle_msg(&mut self, _msg: LoadProjectUsers, _ctx: &mut Self::Context) -> WsResult {
|
||||||
let project_id = current_user(user).map(|u| u.project_id)?;
|
use crate::db::users::LoadProjectUsers as Msg;
|
||||||
let m = match db.send(LoadProjectUsers { project_id }).await {
|
|
||||||
|
let project_id = current_user(&self.current_user).map(|u| u.project_id)?;
|
||||||
|
let m = match block_on(self.db.send(Msg { project_id })) {
|
||||||
Ok(Ok(v)) => Some(WsMsg::ProjectUsersLoaded(
|
Ok(Ok(v)) => Some(WsMsg::ProjectUsersLoaded(
|
||||||
v.into_iter().map(|i| i.into()).collect(),
|
v.into_iter().map(|i| i.into()).collect(),
|
||||||
)),
|
)),
|
||||||
@ -22,29 +21,30 @@ pub async fn load_project_users(
|
|||||||
};
|
};
|
||||||
Ok(m)
|
Ok(m)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn register(
|
pub struct Register {
|
||||||
db: &Data<Addr<DbExecutor>>,
|
pub name: String,
|
||||||
mail: &Data<Addr<MailExecutor>>,
|
pub email: String,
|
||||||
name: String,
|
}
|
||||||
email: String,
|
|
||||||
) -> WsResult {
|
impl WsHandler<Register> for WebSocketActor {
|
||||||
let msg = match db
|
fn handle_msg(&mut self, msg: Register, ctx: &mut Self::Context) -> WsResult {
|
||||||
.send(Register {
|
let Register { name, email } = msg;
|
||||||
|
let msg = match block_on(self.db.send(DbRegister {
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
email: email.clone(),
|
email: email.clone(),
|
||||||
})
|
})) {
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(Ok(_)) => Some(WsMsg::SignUpSuccess),
|
Ok(Ok(_)) => Some(WsMsg::SignUpSuccess),
|
||||||
Ok(Err(_)) => Some(WsMsg::SignUpPairTaken),
|
Ok(Err(_)) => Some(WsMsg::SignUpPairTaken),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
match authenticate(db, mail, name, email).await {
|
match self.handle_msg(Authenticate { name, email }, ctx) {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(e) => return Ok(Some(e)),
|
Err(e) => return Ok(Some(e)),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(msg)
|
Ok(msg)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user