2019-03-21 01:22:31 +00:00
|
|
|
//! `ChatServer` is an actor. It maintains list of connection client session.
|
|
|
|
//! And manages available rooms. Peers send messages to other peers in same
|
|
|
|
//! room through `ChatServer`.
|
|
|
|
|
|
|
|
use actix::prelude::*;
|
|
|
|
use rand::{rngs::ThreadRng, Rng};
|
|
|
|
use std::collections::{HashMap, HashSet};
|
|
|
|
use serde::{Deserialize, Serialize};
|
2019-03-29 04:56:23 +00:00
|
|
|
use serde_json::{Value};
|
2019-03-23 01:42:57 +00:00
|
|
|
use bcrypt::{verify};
|
2019-03-25 03:51:27 +00:00
|
|
|
use std::str::FromStr;
|
2019-03-21 01:22:31 +00:00
|
|
|
|
2019-04-08 05:19:02 +00:00
|
|
|
use {Crud, Joinable, Likeable, Followable, establish_connection, naive_now, SortType};
|
2019-03-23 01:42:57 +00:00
|
|
|
use actions::community::*;
|
2019-03-25 03:51:27 +00:00
|
|
|
use actions::user::*;
|
2019-03-26 18:00:18 +00:00
|
|
|
use actions::post::*;
|
|
|
|
use actions::comment::*;
|
2019-04-03 06:49:32 +00:00
|
|
|
use actions::post_view::*;
|
2019-04-03 20:59:37 +00:00
|
|
|
use actions::comment_view::*;
|
2019-04-03 23:01:20 +00:00
|
|
|
use actions::category::*;
|
|
|
|
use actions::community_view::*;
|
2019-04-08 05:19:02 +00:00
|
|
|
use actions::user_view::*;
|
2019-03-21 01:22:31 +00:00
|
|
|
|
|
|
|
#[derive(EnumString,ToString,Debug)]
|
|
|
|
pub enum UserOperation {
|
2019-04-08 05:19:02 +00:00
|
|
|
Login, Register, CreateCommunity, CreatePost, ListCommunities, ListCategories, GetPost, GetCommunity, CreateComment, EditComment, CreateCommentLike, GetPosts, CreatePostLike, EditPost, EditCommunity, FollowCommunity, GetFollowedCommunities, GetUserDetails
|
2019-03-23 01:42:57 +00:00
|
|
|
}
|
2019-03-21 01:22:31 +00:00
|
|
|
|
2019-03-23 01:42:57 +00:00
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct ErrorMessage {
|
|
|
|
op: String,
|
|
|
|
error: String
|
|
|
|
}
|
2019-03-21 01:22:31 +00:00
|
|
|
|
|
|
|
/// Chat server sends this messages to session
|
|
|
|
#[derive(Message)]
|
|
|
|
pub struct WSMessage(pub String);
|
|
|
|
|
|
|
|
/// Message for chat server communications
|
|
|
|
|
|
|
|
/// New chat session is created
|
|
|
|
#[derive(Message)]
|
|
|
|
#[rtype(usize)]
|
|
|
|
pub struct Connect {
|
|
|
|
pub addr: Recipient<WSMessage>,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Session is disconnected
|
|
|
|
#[derive(Message)]
|
|
|
|
pub struct Disconnect {
|
|
|
|
pub id: usize,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Send message to specific room
|
|
|
|
#[derive(Message)]
|
|
|
|
pub struct ClientMessage {
|
|
|
|
/// Id of the client session
|
|
|
|
pub id: usize,
|
|
|
|
/// Peer message
|
|
|
|
pub msg: String,
|
|
|
|
/// Room name
|
|
|
|
pub room: String,
|
|
|
|
}
|
|
|
|
|
2019-03-25 03:51:27 +00:00
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct StandardMessage {
|
|
|
|
/// Id of the client session
|
|
|
|
pub id: usize,
|
|
|
|
/// Peer message
|
|
|
|
pub msg: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl actix::Message for StandardMessage {
|
|
|
|
type Result = String;
|
|
|
|
}
|
|
|
|
|
2019-03-21 01:22:31 +00:00
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct Login {
|
2019-03-23 01:42:57 +00:00
|
|
|
pub username_or_email: String,
|
2019-03-21 01:22:31 +00:00
|
|
|
pub password: String
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct Register {
|
|
|
|
username: String,
|
|
|
|
email: Option<String>,
|
|
|
|
password: String,
|
|
|
|
password_verify: String
|
|
|
|
}
|
|
|
|
|
2019-03-23 01:42:57 +00:00
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct LoginResponse {
|
|
|
|
op: String,
|
|
|
|
jwt: String
|
|
|
|
}
|
|
|
|
|
2019-03-25 03:51:27 +00:00
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct CreateCommunity {
|
|
|
|
name: String,
|
2019-04-03 20:59:37 +00:00
|
|
|
title: String,
|
|
|
|
description: Option<String>,
|
|
|
|
category_id: i32 ,
|
2019-03-26 18:00:18 +00:00
|
|
|
auth: String
|
2019-03-23 01:42:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize)]
|
2019-04-04 22:29:14 +00:00
|
|
|
pub struct CommunityResponse {
|
2019-03-23 01:42:57 +00:00
|
|
|
op: String,
|
2019-04-03 23:01:20 +00:00
|
|
|
community: CommunityView
|
2019-03-26 18:00:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize)]
|
2019-04-05 06:26:38 +00:00
|
|
|
pub struct ListCommunities {
|
|
|
|
auth: Option<String>
|
|
|
|
}
|
2019-03-26 18:00:18 +00:00
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct ListCommunitiesResponse {
|
|
|
|
op: String,
|
2019-04-03 23:01:20 +00:00
|
|
|
communities: Vec<CommunityView>
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct ListCategories;
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct ListCategoriesResponse {
|
|
|
|
op: String,
|
|
|
|
categories: Vec<Category>
|
2019-03-26 18:00:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct CreatePost {
|
|
|
|
name: String,
|
|
|
|
url: Option<String>,
|
|
|
|
body: Option<String>,
|
|
|
|
community_id: i32,
|
|
|
|
auth: String
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize)]
|
2019-04-03 20:59:37 +00:00
|
|
|
pub struct PostResponse {
|
2019-03-26 18:00:18 +00:00
|
|
|
op: String,
|
2019-04-03 20:59:37 +00:00
|
|
|
post: PostView
|
2019-03-26 18:00:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct GetPost {
|
2019-03-28 19:32:08 +00:00
|
|
|
id: i32,
|
|
|
|
auth: Option<String>
|
2019-03-26 18:00:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct GetPostResponse {
|
|
|
|
op: String,
|
2019-04-03 06:49:32 +00:00
|
|
|
post: PostView,
|
2019-04-03 23:01:20 +00:00
|
|
|
comments: Vec<CommentView>,
|
2019-04-04 20:53:32 +00:00
|
|
|
community: CommunityView,
|
|
|
|
moderators: Vec<CommunityModeratorView>
|
2019-03-26 18:00:18 +00:00
|
|
|
}
|
|
|
|
|
2019-04-03 06:49:32 +00:00
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct GetPosts {
|
|
|
|
type_: String,
|
|
|
|
sort: String,
|
|
|
|
limit: i64,
|
|
|
|
community_id: Option<i32>,
|
|
|
|
auth: Option<String>
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct GetPostsResponse {
|
|
|
|
op: String,
|
|
|
|
posts: Vec<PostView>,
|
|
|
|
}
|
|
|
|
|
2019-03-26 18:00:18 +00:00
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct GetCommunity {
|
2019-04-05 06:26:38 +00:00
|
|
|
id: i32,
|
|
|
|
auth: Option<String>
|
2019-03-26 18:00:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct GetCommunityResponse {
|
|
|
|
op: String,
|
2019-04-04 20:53:32 +00:00
|
|
|
community: CommunityView,
|
|
|
|
moderators: Vec<CommunityModeratorView>
|
2019-03-26 18:00:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct CreateComment {
|
|
|
|
content: String,
|
|
|
|
parent_id: Option<i32>,
|
2019-03-29 04:56:23 +00:00
|
|
|
edit_id: Option<i32>,
|
2019-03-26 18:00:18 +00:00
|
|
|
post_id: i32,
|
|
|
|
auth: String
|
|
|
|
}
|
|
|
|
|
2019-03-29 04:56:23 +00:00
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct EditComment {
|
|
|
|
content: String,
|
|
|
|
parent_id: Option<i32>,
|
|
|
|
edit_id: i32,
|
|
|
|
post_id: i32,
|
|
|
|
auth: String
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize)]
|
2019-04-03 20:59:37 +00:00
|
|
|
pub struct CommentResponse {
|
2019-03-29 04:56:23 +00:00
|
|
|
op: String,
|
|
|
|
comment: CommentView
|
|
|
|
}
|
|
|
|
|
2019-03-28 19:32:08 +00:00
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct CreateCommentLike {
|
|
|
|
comment_id: i32,
|
|
|
|
post_id: i32,
|
|
|
|
score: i16,
|
|
|
|
auth: String
|
|
|
|
}
|
|
|
|
|
2019-04-03 06:49:32 +00:00
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct CreatePostLike {
|
|
|
|
post_id: i32,
|
|
|
|
score: i16,
|
|
|
|
auth: String
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct CreatePostLikeResponse {
|
|
|
|
op: String,
|
|
|
|
post: PostView
|
|
|
|
}
|
|
|
|
|
2019-04-03 20:59:37 +00:00
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct EditPost {
|
|
|
|
edit_id: i32,
|
|
|
|
community_id: i32,
|
|
|
|
name: String,
|
|
|
|
url: Option<String>,
|
|
|
|
body: Option<String>,
|
|
|
|
auth: String
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct EditCommunity {
|
|
|
|
edit_id: i32,
|
2019-04-04 22:29:14 +00:00
|
|
|
name: String,
|
2019-04-03 20:59:37 +00:00
|
|
|
title: String,
|
|
|
|
description: Option<String>,
|
|
|
|
category_id: i32,
|
|
|
|
auth: String
|
|
|
|
}
|
|
|
|
|
2019-04-05 06:26:38 +00:00
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct FollowCommunity {
|
|
|
|
community_id: i32,
|
|
|
|
follow: bool,
|
|
|
|
auth: String
|
|
|
|
}
|
|
|
|
|
2019-04-05 19:14:54 +00:00
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct GetFollowedCommunities {
|
|
|
|
auth: String
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct GetFollowedCommunitiesResponse {
|
|
|
|
op: String,
|
|
|
|
communities: Vec<CommunityFollowerView>
|
|
|
|
}
|
|
|
|
|
2019-04-08 05:19:02 +00:00
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct GetUserDetails {
|
|
|
|
user_id: i32,
|
|
|
|
sort: String,
|
|
|
|
limit: i64,
|
|
|
|
community_id: Option<i32>,
|
|
|
|
auth: Option<String>
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct GetUserDetailsResponse {
|
|
|
|
op: String,
|
|
|
|
user: UserView,
|
|
|
|
follows: Vec<CommunityFollowerView>,
|
|
|
|
moderates: Vec<CommunityModeratorView>,
|
|
|
|
comments: Vec<CommentView>,
|
|
|
|
posts: Vec<PostView>,
|
|
|
|
saved_posts: Vec<PostView>,
|
|
|
|
saved_comments: Vec<CommentView>,
|
|
|
|
}
|
2019-04-05 19:14:54 +00:00
|
|
|
|
2019-03-21 01:22:31 +00:00
|
|
|
/// `ChatServer` manages chat rooms and responsible for coordinating chat
|
|
|
|
/// session. implementation is super primitive
|
|
|
|
pub struct ChatServer {
|
|
|
|
sessions: HashMap<usize, Recipient<WSMessage>>, // A map from generated random ID to session addr
|
2019-03-27 16:59:21 +00:00
|
|
|
rooms: HashMap<i32, HashSet<usize>>, // A map from room / post name to set of connectionIDs
|
2019-03-21 01:22:31 +00:00
|
|
|
rng: ThreadRng,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for ChatServer {
|
|
|
|
fn default() -> ChatServer {
|
|
|
|
// default room
|
2019-03-27 16:59:21 +00:00
|
|
|
let rooms = HashMap::new();
|
2019-03-21 01:22:31 +00:00
|
|
|
|
|
|
|
ChatServer {
|
|
|
|
sessions: HashMap::new(),
|
|
|
|
rooms: rooms,
|
|
|
|
rng: rand::thread_rng(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ChatServer {
|
|
|
|
/// Send message to all users in the room
|
2019-03-27 16:59:21 +00:00
|
|
|
fn send_room_message(&self, room: i32, message: &str, skip_id: usize) {
|
|
|
|
if let Some(sessions) = self.rooms.get(&room) {
|
2019-03-21 01:22:31 +00:00
|
|
|
for id in sessions {
|
|
|
|
if *id != skip_id {
|
|
|
|
if let Some(addr) = self.sessions.get(id) {
|
|
|
|
let _ = addr.do_send(WSMessage(message.to_owned()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-03-25 03:51:27 +00:00
|
|
|
|
2019-04-03 20:59:37 +00:00
|
|
|
// /// Send message only to self
|
|
|
|
// fn send(&self, message: &str, id: &usize) {
|
|
|
|
// // println!("{:?}", self.sessions);
|
|
|
|
// if let Some(addr) = self.sessions.get(id) {
|
|
|
|
// println!("msg: {}", message);
|
|
|
|
// // println!("{:?}", addr.connected());
|
|
|
|
// let _ = addr.do_send(WSMessage(message.to_owned()));
|
|
|
|
// }
|
|
|
|
// }
|
2019-03-21 01:22:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Make actor from `ChatServer`
|
|
|
|
impl Actor for ChatServer {
|
|
|
|
/// We are going to use simple Context, we just need ability to communicate
|
|
|
|
/// with other actors.
|
|
|
|
type Context = Context<Self>;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Handler for Connect message.
|
|
|
|
///
|
|
|
|
/// Register new session and assign unique id to this session
|
|
|
|
impl Handler<Connect> for ChatServer {
|
|
|
|
type Result = usize;
|
|
|
|
|
|
|
|
fn handle(&mut self, msg: Connect, _: &mut Context<Self>) -> Self::Result {
|
|
|
|
println!("Someone joined");
|
|
|
|
|
|
|
|
// notify all users in same room
|
2019-03-27 16:59:21 +00:00
|
|
|
// self.send_room_message(&"Main".to_owned(), "Someone joined", 0);
|
2019-03-21 01:22:31 +00:00
|
|
|
|
|
|
|
// register session with random id
|
|
|
|
let id = self.rng.gen::<usize>();
|
|
|
|
self.sessions.insert(id, msg.addr);
|
|
|
|
|
|
|
|
// auto join session to Main room
|
2019-03-27 16:59:21 +00:00
|
|
|
// self.rooms.get_mut(&"Main".to_owned()).unwrap().insert(id);
|
2019-03-21 01:22:31 +00:00
|
|
|
|
|
|
|
// send id back
|
|
|
|
id
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Handler for Disconnect message.
|
|
|
|
impl Handler<Disconnect> for ChatServer {
|
|
|
|
type Result = ();
|
|
|
|
|
|
|
|
fn handle(&mut self, msg: Disconnect, _: &mut Context<Self>) {
|
|
|
|
println!("Someone disconnected");
|
|
|
|
|
2019-04-03 20:59:37 +00:00
|
|
|
// let mut rooms: Vec<i32> = Vec::new();
|
2019-03-21 01:22:31 +00:00
|
|
|
|
|
|
|
// remove address
|
|
|
|
if self.sessions.remove(&msg.id).is_some() {
|
|
|
|
// remove session from all rooms
|
2019-04-03 20:59:37 +00:00
|
|
|
for (_id, sessions) in &mut self.rooms {
|
2019-03-21 01:22:31 +00:00
|
|
|
if sessions.remove(&msg.id) {
|
2019-03-27 16:59:21 +00:00
|
|
|
// rooms.push(*id);
|
2019-03-21 01:22:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// send message to other users
|
2019-03-27 16:59:21 +00:00
|
|
|
// for room in rooms {
|
2019-04-03 23:01:20 +00:00
|
|
|
// self.send_room_message(room, "Someone disconnected", 0);
|
2019-03-27 16:59:21 +00:00
|
|
|
// }
|
2019-03-21 01:22:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Handler for Message message.
|
2019-03-27 16:59:21 +00:00
|
|
|
// impl Handler<ClientMessage> for ChatServer {
|
|
|
|
// type Result = ();
|
2019-03-21 01:22:31 +00:00
|
|
|
|
2019-03-27 16:59:21 +00:00
|
|
|
// fn handle(&mut self, msg: ClientMessage, _: &mut Context<Self>) {
|
|
|
|
// self.send_room_message(&msg.room, msg.msg.as_str(), msg.id);
|
|
|
|
// }
|
|
|
|
// }
|
2019-03-21 01:22:31 +00:00
|
|
|
|
2019-03-25 03:51:27 +00:00
|
|
|
/// Handler for Message message.
|
|
|
|
impl Handler<StandardMessage> for ChatServer {
|
|
|
|
type Result = MessageResult<StandardMessage>;
|
|
|
|
|
|
|
|
fn handle(&mut self, msg: StandardMessage, _: &mut Context<Self>) -> Self::Result {
|
|
|
|
|
|
|
|
let json: Value = serde_json::from_str(&msg.msg)
|
|
|
|
.expect("Couldn't parse message");
|
|
|
|
|
|
|
|
let data: &Value = &json["data"];
|
|
|
|
let op = &json["op"].as_str().unwrap();
|
|
|
|
let user_operation: UserOperation = UserOperation::from_str(&op).unwrap();
|
|
|
|
|
|
|
|
let res: String = match user_operation {
|
|
|
|
UserOperation::Login => {
|
|
|
|
let login: Login = serde_json::from_str(&data.to_string()).unwrap();
|
2019-03-27 16:59:21 +00:00
|
|
|
login.perform(self, msg.id)
|
2019-03-25 03:51:27 +00:00
|
|
|
},
|
|
|
|
UserOperation::Register => {
|
|
|
|
let register: Register = serde_json::from_str(&data.to_string()).unwrap();
|
2019-03-27 16:59:21 +00:00
|
|
|
register.perform(self, msg.id)
|
2019-03-25 03:51:27 +00:00
|
|
|
},
|
|
|
|
UserOperation::CreateCommunity => {
|
|
|
|
let create_community: CreateCommunity = serde_json::from_str(&data.to_string()).unwrap();
|
2019-03-27 16:59:21 +00:00
|
|
|
create_community.perform(self, msg.id)
|
2019-03-26 18:00:18 +00:00
|
|
|
},
|
|
|
|
UserOperation::ListCommunities => {
|
2019-04-05 06:26:38 +00:00
|
|
|
let list_communities: ListCommunities = serde_json::from_str(&data.to_string()).unwrap();
|
2019-03-27 16:59:21 +00:00
|
|
|
list_communities.perform(self, msg.id)
|
2019-03-26 18:00:18 +00:00
|
|
|
},
|
2019-04-03 23:01:20 +00:00
|
|
|
UserOperation::ListCategories => {
|
|
|
|
let list_categories: ListCategories = ListCategories;
|
|
|
|
list_categories.perform(self, msg.id)
|
|
|
|
},
|
2019-03-26 18:00:18 +00:00
|
|
|
UserOperation::CreatePost => {
|
|
|
|
let create_post: CreatePost = serde_json::from_str(&data.to_string()).unwrap();
|
2019-03-27 16:59:21 +00:00
|
|
|
create_post.perform(self, msg.id)
|
2019-03-26 18:00:18 +00:00
|
|
|
},
|
|
|
|
UserOperation::GetPost => {
|
|
|
|
let get_post: GetPost = serde_json::from_str(&data.to_string()).unwrap();
|
2019-03-27 16:59:21 +00:00
|
|
|
get_post.perform(self, msg.id)
|
2019-03-26 18:00:18 +00:00
|
|
|
},
|
|
|
|
UserOperation::GetCommunity => {
|
|
|
|
let get_community: GetCommunity = serde_json::from_str(&data.to_string()).unwrap();
|
2019-03-27 16:59:21 +00:00
|
|
|
get_community.perform(self, msg.id)
|
2019-03-26 18:00:18 +00:00
|
|
|
},
|
|
|
|
UserOperation::CreateComment => {
|
|
|
|
let create_comment: CreateComment = serde_json::from_str(&data.to_string()).unwrap();
|
2019-03-27 16:59:21 +00:00
|
|
|
create_comment.perform(self, msg.id)
|
2019-03-25 03:51:27 +00:00
|
|
|
},
|
2019-03-29 04:56:23 +00:00
|
|
|
UserOperation::EditComment => {
|
|
|
|
let edit_comment: EditComment = serde_json::from_str(&data.to_string()).unwrap();
|
|
|
|
edit_comment.perform(self, msg.id)
|
|
|
|
},
|
2019-03-28 19:32:08 +00:00
|
|
|
UserOperation::CreateCommentLike => {
|
|
|
|
let create_comment_like: CreateCommentLike = serde_json::from_str(&data.to_string()).unwrap();
|
|
|
|
create_comment_like.perform(self, msg.id)
|
|
|
|
},
|
2019-04-03 06:49:32 +00:00
|
|
|
UserOperation::GetPosts => {
|
|
|
|
let get_posts: GetPosts = serde_json::from_str(&data.to_string()).unwrap();
|
|
|
|
get_posts.perform(self, msg.id)
|
|
|
|
},
|
|
|
|
UserOperation::CreatePostLike => {
|
|
|
|
let create_post_like: CreatePostLike = serde_json::from_str(&data.to_string()).unwrap();
|
|
|
|
create_post_like.perform(self, msg.id)
|
|
|
|
},
|
2019-04-03 20:59:37 +00:00
|
|
|
UserOperation::EditPost => {
|
|
|
|
let edit_post: EditPost = serde_json::from_str(&data.to_string()).unwrap();
|
|
|
|
edit_post.perform(self, msg.id)
|
|
|
|
},
|
2019-04-04 22:29:14 +00:00
|
|
|
UserOperation::EditCommunity => {
|
|
|
|
let edit_community: EditCommunity = serde_json::from_str(&data.to_string()).unwrap();
|
|
|
|
edit_community.perform(self, msg.id)
|
|
|
|
},
|
2019-04-05 06:26:38 +00:00
|
|
|
UserOperation::FollowCommunity => {
|
|
|
|
let follow_community: FollowCommunity = serde_json::from_str(&data.to_string()).unwrap();
|
|
|
|
follow_community.perform(self, msg.id)
|
|
|
|
},
|
2019-04-05 19:14:54 +00:00
|
|
|
UserOperation::GetFollowedCommunities => {
|
|
|
|
let followed_communities: GetFollowedCommunities = serde_json::from_str(&data.to_string()).unwrap();
|
|
|
|
followed_communities.perform(self, msg.id)
|
|
|
|
},
|
2019-04-08 05:19:02 +00:00
|
|
|
UserOperation::GetUserDetails => {
|
|
|
|
let get_user_details: GetUserDetails = serde_json::from_str(&data.to_string()).unwrap();
|
|
|
|
get_user_details.perform(self, msg.id)
|
|
|
|
},
|
|
|
|
// _ => {
|
|
|
|
// let e = ErrorMessage {
|
|
|
|
// op: "Unknown".to_string(),
|
|
|
|
// error: "Unknown User Operation".to_string()
|
|
|
|
// };
|
|
|
|
// serde_json::to_string(&e).unwrap()
|
|
|
|
// }
|
2019-03-25 03:51:27 +00:00
|
|
|
};
|
2019-03-21 01:22:31 +00:00
|
|
|
|
2019-03-25 03:51:27 +00:00
|
|
|
MessageResult(res)
|
2019-03-21 01:22:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-25 03:51:27 +00:00
|
|
|
|
|
|
|
pub trait Perform {
|
2019-04-03 20:59:37 +00:00
|
|
|
fn perform(&self, _chat: &mut ChatServer, _addr: usize) -> String;
|
2019-03-26 18:00:18 +00:00
|
|
|
fn op_type(&self) -> UserOperation;
|
|
|
|
fn error(&self, error_msg: &str) -> String {
|
|
|
|
serde_json::to_string(
|
|
|
|
&ErrorMessage {
|
|
|
|
op: self.op_type().to_string(),
|
|
|
|
error: error_msg.to_string()
|
|
|
|
}
|
|
|
|
)
|
|
|
|
.unwrap()
|
|
|
|
}
|
2019-03-25 03:51:27 +00:00
|
|
|
}
|
2019-03-21 01:22:31 +00:00
|
|
|
|
2019-03-25 03:51:27 +00:00
|
|
|
impl Perform for Login {
|
2019-03-26 18:00:18 +00:00
|
|
|
fn op_type(&self) -> UserOperation {
|
|
|
|
UserOperation::Login
|
|
|
|
}
|
2019-04-03 20:59:37 +00:00
|
|
|
fn perform(&self, _chat: &mut ChatServer, _addr: usize) -> String {
|
2019-03-23 01:42:57 +00:00
|
|
|
|
|
|
|
let conn = establish_connection();
|
2019-03-21 01:22:31 +00:00
|
|
|
|
2019-03-23 01:42:57 +00:00
|
|
|
// Fetch that username / email
|
2019-03-25 03:51:27 +00:00
|
|
|
let user: User_ = match User_::find_by_email_or_username(&conn, &self.username_or_email) {
|
2019-03-23 01:42:57 +00:00
|
|
|
Ok(user) => user,
|
2019-04-03 20:59:37 +00:00
|
|
|
Err(_e) => return self.error("Couldn't find that username or email")
|
2019-03-23 01:42:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// Verify the password
|
2019-03-25 03:51:27 +00:00
|
|
|
let valid: bool = verify(&self.password, &user.password_encrypted).unwrap_or(false);
|
2019-03-23 01:42:57 +00:00
|
|
|
if !valid {
|
2019-03-26 18:00:18 +00:00
|
|
|
return self.error("Password incorrect")
|
2019-03-23 01:42:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Return the jwt
|
2019-03-25 03:51:27 +00:00
|
|
|
serde_json::to_string(
|
|
|
|
&LoginResponse {
|
2019-03-26 18:00:18 +00:00
|
|
|
op: self.op_type().to_string(),
|
2019-03-25 03:51:27 +00:00
|
|
|
jwt: user.jwt()
|
|
|
|
}
|
2019-03-23 01:42:57 +00:00
|
|
|
)
|
2019-03-25 03:51:27 +00:00
|
|
|
.unwrap()
|
2019-03-21 01:22:31 +00:00
|
|
|
}
|
2019-03-26 18:00:18 +00:00
|
|
|
|
2019-03-21 01:22:31 +00:00
|
|
|
}
|
|
|
|
|
2019-03-25 03:51:27 +00:00
|
|
|
impl Perform for Register {
|
2019-03-26 18:00:18 +00:00
|
|
|
fn op_type(&self) -> UserOperation {
|
|
|
|
UserOperation::Register
|
|
|
|
}
|
2019-04-03 20:59:37 +00:00
|
|
|
fn perform(&self, _chat: &mut ChatServer, _addr: usize) -> String {
|
2019-03-21 01:22:31 +00:00
|
|
|
|
|
|
|
let conn = establish_connection();
|
|
|
|
|
2019-03-23 01:42:57 +00:00
|
|
|
// Make sure passwords match
|
2019-03-25 03:51:27 +00:00
|
|
|
if &self.password != &self.password_verify {
|
2019-03-26 18:00:18 +00:00
|
|
|
return self.error("Passwords do not match.");
|
2019-03-23 01:42:57 +00:00
|
|
|
}
|
2019-03-21 01:22:31 +00:00
|
|
|
|
|
|
|
// Register the new user
|
|
|
|
let user_form = UserForm {
|
2019-03-25 03:51:27 +00:00
|
|
|
name: self.username.to_owned(),
|
2019-04-03 06:49:32 +00:00
|
|
|
fedi_name: "rrf".into(),
|
2019-03-25 03:51:27 +00:00
|
|
|
email: self.email.to_owned(),
|
|
|
|
password_encrypted: self.password.to_owned(),
|
2019-03-21 01:22:31 +00:00
|
|
|
preferred_username: None,
|
|
|
|
updated: None
|
|
|
|
};
|
|
|
|
|
2019-03-23 01:42:57 +00:00
|
|
|
// Create the user
|
|
|
|
let inserted_user = match User_::create(&conn, &user_form) {
|
|
|
|
Ok(user) => user,
|
2019-04-03 20:59:37 +00:00
|
|
|
Err(_e) => {
|
2019-03-26 18:00:18 +00:00
|
|
|
return self.error("User already exists.");
|
2019-03-25 03:51:27 +00:00
|
|
|
}
|
2019-03-23 01:42:57 +00:00
|
|
|
};
|
2019-03-21 01:22:31 +00:00
|
|
|
|
|
|
|
// Return the jwt
|
2019-03-25 03:51:27 +00:00
|
|
|
serde_json::to_string(
|
|
|
|
&LoginResponse {
|
2019-03-26 18:00:18 +00:00
|
|
|
op: self.op_type().to_string(),
|
2019-03-25 03:51:27 +00:00
|
|
|
jwt: inserted_user.jwt()
|
|
|
|
}
|
2019-03-23 01:42:57 +00:00
|
|
|
)
|
2019-03-25 03:51:27 +00:00
|
|
|
.unwrap()
|
2019-03-21 01:22:31 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
}
|
2019-03-23 01:42:57 +00:00
|
|
|
|
2019-03-26 18:00:18 +00:00
|
|
|
impl Perform for CreateCommunity {
|
|
|
|
fn op_type(&self) -> UserOperation {
|
|
|
|
UserOperation::CreateCommunity
|
|
|
|
}
|
|
|
|
|
2019-04-03 20:59:37 +00:00
|
|
|
fn perform(&self, _chat: &mut ChatServer, _addr: usize) -> String {
|
2019-03-25 03:51:27 +00:00
|
|
|
|
|
|
|
let conn = establish_connection();
|
|
|
|
|
2019-03-26 18:00:18 +00:00
|
|
|
let claims = match Claims::decode(&self.auth) {
|
2019-03-25 03:51:27 +00:00
|
|
|
Ok(claims) => claims.claims,
|
2019-04-03 20:59:37 +00:00
|
|
|
Err(_e) => {
|
2019-03-26 18:00:18 +00:00
|
|
|
return self.error("Not logged in.");
|
2019-03-25 03:51:27 +00:00
|
|
|
}
|
|
|
|
};
|
2019-03-23 01:42:57 +00:00
|
|
|
|
2019-03-25 03:51:27 +00:00
|
|
|
let user_id = claims.id;
|
2019-04-03 06:49:32 +00:00
|
|
|
|
|
|
|
// When you create a community, make sure the user becomes a moderator and a follower
|
2019-03-23 01:42:57 +00:00
|
|
|
|
2019-03-25 03:51:27 +00:00
|
|
|
let community_form = CommunityForm {
|
|
|
|
name: self.name.to_owned(),
|
2019-04-03 20:59:37 +00:00
|
|
|
title: self.title.to_owned(),
|
|
|
|
description: self.description.to_owned(),
|
|
|
|
category_id: self.category_id,
|
2019-04-03 06:49:32 +00:00
|
|
|
creator_id: user_id,
|
2019-03-25 03:51:27 +00:00
|
|
|
updated: None
|
|
|
|
};
|
2019-03-23 01:42:57 +00:00
|
|
|
|
2019-03-25 03:51:27 +00:00
|
|
|
let inserted_community = match Community::create(&conn, &community_form) {
|
2019-03-23 01:42:57 +00:00
|
|
|
Ok(community) => community,
|
2019-04-03 20:59:37 +00:00
|
|
|
Err(_e) => {
|
2019-03-26 18:00:18 +00:00
|
|
|
return self.error("Community already exists.");
|
2019-03-25 03:51:27 +00:00
|
|
|
}
|
2019-03-23 01:42:57 +00:00
|
|
|
};
|
2019-03-25 03:51:27 +00:00
|
|
|
|
2019-04-03 06:49:32 +00:00
|
|
|
let community_moderator_form = CommunityModeratorForm {
|
2019-03-25 03:51:27 +00:00
|
|
|
community_id: inserted_community.id,
|
2019-04-03 06:49:32 +00:00
|
|
|
user_id: user_id
|
2019-03-25 03:51:27 +00:00
|
|
|
};
|
|
|
|
|
2019-04-03 20:59:37 +00:00
|
|
|
let _inserted_community_moderator = match CommunityModerator::join(&conn, &community_moderator_form) {
|
2019-03-25 03:51:27 +00:00
|
|
|
Ok(user) => user,
|
2019-04-03 20:59:37 +00:00
|
|
|
Err(_e) => {
|
2019-04-03 06:49:32 +00:00
|
|
|
return self.error("Community moderator already exists.");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
let community_follower_form = CommunityFollowerForm {
|
|
|
|
community_id: inserted_community.id,
|
|
|
|
user_id: user_id
|
|
|
|
};
|
|
|
|
|
2019-04-03 20:59:37 +00:00
|
|
|
let _inserted_community_follower = match CommunityFollower::follow(&conn, &community_follower_form) {
|
2019-04-03 06:49:32 +00:00
|
|
|
Ok(user) => user,
|
2019-04-03 20:59:37 +00:00
|
|
|
Err(_e) => {
|
2019-04-03 06:49:32 +00:00
|
|
|
return self.error("Community follower already exists.");
|
2019-03-25 03:51:27 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-04-05 06:26:38 +00:00
|
|
|
let community_view = CommunityView::read(&conn, inserted_community.id, Some(user_id)).unwrap();
|
2019-04-03 23:01:20 +00:00
|
|
|
|
2019-03-26 18:00:18 +00:00
|
|
|
serde_json::to_string(
|
2019-04-04 22:29:14 +00:00
|
|
|
&CommunityResponse {
|
2019-03-26 18:00:18 +00:00
|
|
|
op: self.op_type().to_string(),
|
2019-04-03 23:01:20 +00:00
|
|
|
community: community_view
|
2019-03-26 18:00:18 +00:00
|
|
|
}
|
|
|
|
)
|
|
|
|
.unwrap()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Perform for ListCommunities {
|
|
|
|
fn op_type(&self) -> UserOperation {
|
|
|
|
UserOperation::ListCommunities
|
|
|
|
}
|
|
|
|
|
2019-04-03 20:59:37 +00:00
|
|
|
fn perform(&self, _chat: &mut ChatServer, _addr: usize) -> String {
|
2019-03-26 18:00:18 +00:00
|
|
|
|
|
|
|
let conn = establish_connection();
|
|
|
|
|
2019-04-05 06:26:38 +00:00
|
|
|
let user_id: Option<i32> = match &self.auth {
|
|
|
|
Some(auth) => {
|
|
|
|
match Claims::decode(&auth) {
|
|
|
|
Ok(claims) => {
|
|
|
|
let user_id = claims.claims.id;
|
|
|
|
Some(user_id)
|
|
|
|
}
|
|
|
|
Err(_e) => None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
None => None
|
|
|
|
};
|
|
|
|
|
|
|
|
let communities: Vec<CommunityView> = CommunityView::list_all(&conn, user_id).unwrap();
|
2019-03-25 03:51:27 +00:00
|
|
|
|
|
|
|
// Return the jwt
|
|
|
|
serde_json::to_string(
|
2019-03-26 18:00:18 +00:00
|
|
|
&ListCommunitiesResponse {
|
|
|
|
op: self.op_type().to_string(),
|
|
|
|
communities: communities
|
|
|
|
}
|
|
|
|
)
|
|
|
|
.unwrap()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-03 23:01:20 +00:00
|
|
|
impl Perform for ListCategories {
|
|
|
|
fn op_type(&self) -> UserOperation {
|
|
|
|
UserOperation::ListCategories
|
|
|
|
}
|
|
|
|
|
|
|
|
fn perform(&self, _chat: &mut ChatServer, _addr: usize) -> String {
|
|
|
|
|
|
|
|
let conn = establish_connection();
|
|
|
|
|
|
|
|
let categories: Vec<Category> = Category::list_all(&conn).unwrap();
|
|
|
|
|
|
|
|
// Return the jwt
|
|
|
|
serde_json::to_string(
|
|
|
|
&ListCategoriesResponse {
|
|
|
|
op: self.op_type().to_string(),
|
|
|
|
categories: categories
|
|
|
|
}
|
|
|
|
)
|
|
|
|
.unwrap()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-26 18:00:18 +00:00
|
|
|
impl Perform for CreatePost {
|
|
|
|
fn op_type(&self) -> UserOperation {
|
|
|
|
UserOperation::CreatePost
|
|
|
|
}
|
|
|
|
|
2019-04-03 20:59:37 +00:00
|
|
|
fn perform(&self, _chat: &mut ChatServer, _addr: usize) -> String {
|
2019-03-26 18:00:18 +00:00
|
|
|
|
|
|
|
let conn = establish_connection();
|
|
|
|
|
|
|
|
let claims = match Claims::decode(&self.auth) {
|
|
|
|
Ok(claims) => claims.claims,
|
2019-04-03 20:59:37 +00:00
|
|
|
Err(_e) => {
|
2019-03-26 18:00:18 +00:00
|
|
|
return self.error("Not logged in.");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
let user_id = claims.id;
|
|
|
|
|
|
|
|
let post_form = PostForm {
|
|
|
|
name: self.name.to_owned(),
|
|
|
|
url: self.url.to_owned(),
|
|
|
|
body: self.body.to_owned(),
|
|
|
|
community_id: self.community_id,
|
2019-04-03 06:49:32 +00:00
|
|
|
creator_id: user_id,
|
2019-03-26 18:00:18 +00:00
|
|
|
updated: None
|
|
|
|
};
|
|
|
|
|
|
|
|
let inserted_post = match Post::create(&conn, &post_form) {
|
|
|
|
Ok(post) => post,
|
2019-04-03 20:59:37 +00:00
|
|
|
Err(_e) => {
|
2019-03-26 18:00:18 +00:00
|
|
|
return self.error("Couldn't create Post");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-04-03 06:49:32 +00:00
|
|
|
// They like their own post by default
|
|
|
|
let like_form = PostLikeForm {
|
|
|
|
post_id: inserted_post.id,
|
|
|
|
user_id: user_id,
|
|
|
|
score: 1
|
|
|
|
};
|
|
|
|
|
|
|
|
// Only add the like if the score isnt 0
|
2019-04-03 20:59:37 +00:00
|
|
|
let _inserted_like = match PostLike::like(&conn, &like_form) {
|
2019-04-03 06:49:32 +00:00
|
|
|
Ok(like) => like,
|
2019-04-03 20:59:37 +00:00
|
|
|
Err(_e) => {
|
2019-04-03 06:49:32 +00:00
|
|
|
return self.error("Couldn't like post.");
|
|
|
|
}
|
|
|
|
};
|
2019-04-03 23:01:20 +00:00
|
|
|
|
2019-04-03 20:59:37 +00:00
|
|
|
// Refetch the view
|
2019-04-03 23:01:20 +00:00
|
|
|
let post_view = match PostView::read(&conn, inserted_post.id, Some(user_id)) {
|
2019-04-03 20:59:37 +00:00
|
|
|
Ok(post) => post,
|
|
|
|
Err(_e) => {
|
|
|
|
return self.error("Couldn't find Post");
|
|
|
|
}
|
|
|
|
};
|
2019-04-03 06:49:32 +00:00
|
|
|
|
2019-03-26 18:00:18 +00:00
|
|
|
serde_json::to_string(
|
2019-04-03 20:59:37 +00:00
|
|
|
&PostResponse {
|
2019-03-26 18:00:18 +00:00
|
|
|
op: self.op_type().to_string(),
|
2019-04-03 20:59:37 +00:00
|
|
|
post: post_view
|
2019-03-26 18:00:18 +00:00
|
|
|
}
|
|
|
|
)
|
|
|
|
.unwrap()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl Perform for GetPost {
|
|
|
|
fn op_type(&self) -> UserOperation {
|
|
|
|
UserOperation::GetPost
|
|
|
|
}
|
|
|
|
|
2019-03-27 16:59:21 +00:00
|
|
|
fn perform(&self, chat: &mut ChatServer, addr: usize) -> String {
|
2019-03-26 18:00:18 +00:00
|
|
|
|
|
|
|
let conn = establish_connection();
|
|
|
|
|
2019-03-28 19:32:08 +00:00
|
|
|
println!("{:?}", self.auth);
|
|
|
|
|
2019-04-03 06:49:32 +00:00
|
|
|
let user_id: Option<i32> = match &self.auth {
|
2019-03-28 19:32:08 +00:00
|
|
|
Some(auth) => {
|
|
|
|
match Claims::decode(&auth) {
|
|
|
|
Ok(claims) => {
|
2019-04-03 06:49:32 +00:00
|
|
|
let user_id = claims.claims.id;
|
|
|
|
Some(user_id)
|
2019-03-28 19:32:08 +00:00
|
|
|
}
|
2019-04-03 20:59:37 +00:00
|
|
|
Err(_e) => None
|
2019-03-28 19:32:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
None => None
|
|
|
|
};
|
|
|
|
|
2019-04-03 23:01:20 +00:00
|
|
|
let post_view = match PostView::read(&conn, self.id, user_id) {
|
2019-03-26 18:00:18 +00:00
|
|
|
Ok(post) => post,
|
2019-04-03 20:59:37 +00:00
|
|
|
Err(_e) => {
|
2019-03-26 18:00:18 +00:00
|
|
|
return self.error("Couldn't find Post");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-03-27 16:59:21 +00:00
|
|
|
// remove session from all rooms
|
2019-04-03 20:59:37 +00:00
|
|
|
for (_n, sessions) in &mut chat.rooms {
|
2019-03-27 16:59:21 +00:00
|
|
|
sessions.remove(&addr);
|
|
|
|
}
|
|
|
|
|
|
|
|
if chat.rooms.get_mut(&self.id).is_none() {
|
|
|
|
chat.rooms.insert(self.id, HashSet::new());
|
|
|
|
}
|
|
|
|
|
|
|
|
chat.rooms.get_mut(&self.id).unwrap().insert(addr);
|
|
|
|
|
2019-04-08 05:19:02 +00:00
|
|
|
let comments = CommentView::list(&conn, &SortType::New, Some(self.id), None, user_id, 999).unwrap();
|
2019-03-27 16:59:21 +00:00
|
|
|
|
2019-04-05 06:26:38 +00:00
|
|
|
let community = CommunityView::read(&conn, post_view.community_id, user_id).unwrap();
|
2019-04-03 23:01:20 +00:00
|
|
|
|
2019-04-04 20:53:32 +00:00
|
|
|
let moderators = CommunityModeratorView::for_community(&conn, post_view.community_id).unwrap();
|
|
|
|
|
2019-03-26 18:00:18 +00:00
|
|
|
// Return the jwt
|
|
|
|
serde_json::to_string(
|
|
|
|
&GetPostResponse {
|
|
|
|
op: self.op_type().to_string(),
|
2019-04-03 06:49:32 +00:00
|
|
|
post: post_view,
|
2019-04-03 23:01:20 +00:00
|
|
|
comments: comments,
|
2019-04-04 20:53:32 +00:00
|
|
|
community: community,
|
|
|
|
moderators: moderators
|
2019-03-25 03:51:27 +00:00
|
|
|
}
|
2019-03-23 01:42:57 +00:00
|
|
|
)
|
2019-03-25 03:51:27 +00:00
|
|
|
.unwrap()
|
2019-03-26 18:00:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Perform for GetCommunity {
|
|
|
|
fn op_type(&self) -> UserOperation {
|
|
|
|
UserOperation::GetCommunity
|
|
|
|
}
|
|
|
|
|
2019-04-03 20:59:37 +00:00
|
|
|
fn perform(&self, _chat: &mut ChatServer, _addr: usize) -> String {
|
2019-03-26 18:00:18 +00:00
|
|
|
|
|
|
|
let conn = establish_connection();
|
2019-03-25 03:51:27 +00:00
|
|
|
|
2019-04-05 06:26:38 +00:00
|
|
|
let user_id: Option<i32> = match &self.auth {
|
|
|
|
Some(auth) => {
|
|
|
|
match Claims::decode(&auth) {
|
|
|
|
Ok(claims) => {
|
|
|
|
let user_id = claims.claims.id;
|
|
|
|
Some(user_id)
|
|
|
|
}
|
|
|
|
Err(_e) => None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
None => None
|
|
|
|
};
|
|
|
|
|
|
|
|
let community_view = match CommunityView::read(&conn, self.id, user_id) {
|
2019-03-26 18:00:18 +00:00
|
|
|
Ok(community) => community,
|
2019-04-03 20:59:37 +00:00
|
|
|
Err(_e) => {
|
2019-03-26 18:00:18 +00:00
|
|
|
return self.error("Couldn't find Community");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-04-04 20:53:32 +00:00
|
|
|
let moderators = match CommunityModeratorView::for_community(&conn, self.id) {
|
|
|
|
Ok(moderators) => moderators,
|
|
|
|
Err(_e) => {
|
|
|
|
return self.error("Couldn't find Community");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-03-26 18:00:18 +00:00
|
|
|
// Return the jwt
|
|
|
|
serde_json::to_string(
|
|
|
|
&GetCommunityResponse {
|
|
|
|
op: self.op_type().to_string(),
|
2019-04-04 20:53:32 +00:00
|
|
|
community: community_view,
|
|
|
|
moderators: moderators
|
2019-03-26 18:00:18 +00:00
|
|
|
}
|
|
|
|
)
|
|
|
|
.unwrap()
|
2019-03-23 01:42:57 +00:00
|
|
|
}
|
|
|
|
}
|
2019-03-26 18:00:18 +00:00
|
|
|
|
|
|
|
impl Perform for CreateComment {
|
|
|
|
fn op_type(&self) -> UserOperation {
|
|
|
|
UserOperation::CreateComment
|
|
|
|
}
|
|
|
|
|
2019-03-27 16:59:21 +00:00
|
|
|
fn perform(&self, chat: &mut ChatServer, addr: usize) -> String {
|
2019-03-26 18:00:18 +00:00
|
|
|
|
|
|
|
let conn = establish_connection();
|
|
|
|
|
|
|
|
let claims = match Claims::decode(&self.auth) {
|
|
|
|
Ok(claims) => claims.claims,
|
2019-04-03 20:59:37 +00:00
|
|
|
Err(_e) => {
|
2019-03-26 18:00:18 +00:00
|
|
|
return self.error("Not logged in.");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
let user_id = claims.id;
|
|
|
|
|
|
|
|
let comment_form = CommentForm {
|
|
|
|
content: self.content.to_owned(),
|
|
|
|
parent_id: self.parent_id.to_owned(),
|
|
|
|
post_id: self.post_id,
|
2019-04-03 06:49:32 +00:00
|
|
|
creator_id: user_id,
|
2019-03-26 18:00:18 +00:00
|
|
|
updated: None
|
|
|
|
};
|
|
|
|
|
|
|
|
let inserted_comment = match Comment::create(&conn, &comment_form) {
|
|
|
|
Ok(comment) => comment,
|
2019-04-03 20:59:37 +00:00
|
|
|
Err(_e) => {
|
2019-03-28 19:53:29 +00:00
|
|
|
return self.error("Couldn't create Comment");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// You like your own comment by default
|
|
|
|
let like_form = CommentLikeForm {
|
|
|
|
comment_id: inserted_comment.id,
|
|
|
|
post_id: self.post_id,
|
2019-04-03 06:49:32 +00:00
|
|
|
user_id: user_id,
|
2019-03-28 19:53:29 +00:00
|
|
|
score: 1
|
|
|
|
};
|
|
|
|
|
2019-04-03 20:59:37 +00:00
|
|
|
let _inserted_like = match CommentLike::like(&conn, &like_form) {
|
2019-03-28 19:53:29 +00:00
|
|
|
Ok(like) => like,
|
2019-04-03 20:59:37 +00:00
|
|
|
Err(_e) => {
|
2019-03-28 19:53:29 +00:00
|
|
|
return self.error("Couldn't like comment.");
|
2019-03-26 18:00:18 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-04-03 20:59:37 +00:00
|
|
|
let comment_view = CommentView::read(&conn, inserted_comment.id, Some(user_id)).unwrap();
|
2019-03-28 19:53:29 +00:00
|
|
|
|
|
|
|
let mut comment_sent = comment_view.clone();
|
|
|
|
comment_sent.my_vote = None;
|
2019-04-03 20:59:37 +00:00
|
|
|
comment_sent.user_id = None;
|
2019-03-28 19:32:08 +00:00
|
|
|
|
2019-03-27 16:59:21 +00:00
|
|
|
let comment_out = serde_json::to_string(
|
2019-04-03 20:59:37 +00:00
|
|
|
&CommentResponse {
|
2019-03-26 18:00:18 +00:00
|
|
|
op: self.op_type().to_string(),
|
2019-03-28 19:32:08 +00:00
|
|
|
comment: comment_view
|
2019-03-26 18:00:18 +00:00
|
|
|
}
|
|
|
|
)
|
2019-03-27 16:59:21 +00:00
|
|
|
.unwrap();
|
|
|
|
|
2019-03-28 19:53:29 +00:00
|
|
|
let comment_sent_out = serde_json::to_string(
|
2019-04-03 20:59:37 +00:00
|
|
|
&CommentResponse {
|
2019-03-28 19:53:29 +00:00
|
|
|
op: self.op_type().to_string(),
|
|
|
|
comment: comment_sent
|
|
|
|
}
|
|
|
|
)
|
|
|
|
.unwrap();
|
2019-04-03 23:01:20 +00:00
|
|
|
|
2019-03-28 19:53:29 +00:00
|
|
|
chat.send_room_message(self.post_id, &comment_sent_out, addr);
|
2019-03-27 16:59:21 +00:00
|
|
|
|
|
|
|
comment_out
|
2019-03-26 18:00:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-29 04:56:23 +00:00
|
|
|
impl Perform for EditComment {
|
|
|
|
fn op_type(&self) -> UserOperation {
|
|
|
|
UserOperation::EditComment
|
|
|
|
}
|
|
|
|
|
|
|
|
fn perform(&self, chat: &mut ChatServer, addr: usize) -> String {
|
|
|
|
|
|
|
|
let conn = establish_connection();
|
|
|
|
|
|
|
|
let claims = match Claims::decode(&self.auth) {
|
|
|
|
Ok(claims) => claims.claims,
|
2019-04-03 20:59:37 +00:00
|
|
|
Err(_e) => {
|
2019-03-29 04:56:23 +00:00
|
|
|
return self.error("Not logged in.");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
let user_id = claims.id;
|
|
|
|
|
2019-04-05 00:25:21 +00:00
|
|
|
// Verify its the creator
|
|
|
|
let orig_comment = Comment::read(&conn, self.edit_id).unwrap();
|
|
|
|
if user_id != orig_comment.creator_id {
|
2019-04-05 06:26:38 +00:00
|
|
|
return self.error("Incorrect creator.");
|
2019-04-05 00:25:21 +00:00
|
|
|
}
|
|
|
|
|
2019-03-29 04:56:23 +00:00
|
|
|
let comment_form = CommentForm {
|
|
|
|
content: self.content.to_owned(),
|
|
|
|
parent_id: self.parent_id,
|
|
|
|
post_id: self.post_id,
|
2019-04-03 06:49:32 +00:00
|
|
|
creator_id: user_id,
|
2019-03-29 04:56:23 +00:00
|
|
|
updated: Some(naive_now())
|
|
|
|
};
|
|
|
|
|
2019-04-03 20:59:37 +00:00
|
|
|
let _updated_comment = match Comment::update(&conn, self.edit_id, &comment_form) {
|
2019-03-29 04:56:23 +00:00
|
|
|
Ok(comment) => comment,
|
2019-04-03 20:59:37 +00:00
|
|
|
Err(_e) => {
|
2019-03-29 04:56:23 +00:00
|
|
|
return self.error("Couldn't update Comment");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2019-04-03 20:59:37 +00:00
|
|
|
let comment_view = CommentView::read(&conn, self.edit_id, Some(user_id)).unwrap();
|
2019-03-29 04:56:23 +00:00
|
|
|
|
|
|
|
let mut comment_sent = comment_view.clone();
|
|
|
|
comment_sent.my_vote = None;
|
2019-04-03 20:59:37 +00:00
|
|
|
comment_sent.user_id = None;
|
2019-03-29 04:56:23 +00:00
|
|
|
|
|
|
|
let comment_out = serde_json::to_string(
|
2019-04-03 20:59:37 +00:00
|
|
|
&CommentResponse {
|
2019-03-29 04:56:23 +00:00
|
|
|
op: self.op_type().to_string(),
|
|
|
|
comment: comment_view
|
|
|
|
}
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
let comment_sent_out = serde_json::to_string(
|
2019-04-03 20:59:37 +00:00
|
|
|
&CommentResponse {
|
2019-03-29 04:56:23 +00:00
|
|
|
op: self.op_type().to_string(),
|
|
|
|
comment: comment_sent
|
|
|
|
}
|
|
|
|
)
|
|
|
|
.unwrap();
|
2019-04-03 23:01:20 +00:00
|
|
|
|
2019-03-29 04:56:23 +00:00
|
|
|
chat.send_room_message(self.post_id, &comment_sent_out, addr);
|
|
|
|
|
|
|
|
comment_out
|
|
|
|
}
|
|
|
|
}
|
2019-03-26 18:00:18 +00:00
|
|
|
|
2019-03-28 19:32:08 +00:00
|
|
|
impl Perform for CreateCommentLike {
|
|
|
|
fn op_type(&self) -> UserOperation {
|
|
|
|
UserOperation::CreateCommentLike
|
|
|
|
}
|
|
|
|
|
|
|
|
fn perform(&self, chat: &mut ChatServer, addr: usize) -> String {
|
|
|
|
|
|
|
|
let conn = establish_connection();
|
|
|
|
|
|
|
|
let claims = match Claims::decode(&self.auth) {
|
|
|
|
Ok(claims) => claims.claims,
|
2019-04-03 20:59:37 +00:00
|
|
|
Err(_e) => {
|
2019-03-28 19:32:08 +00:00
|
|
|
return self.error("Not logged in.");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
let user_id = claims.id;
|
|
|
|
|
|
|
|
let like_form = CommentLikeForm {
|
|
|
|
comment_id: self.comment_id,
|
|
|
|
post_id: self.post_id,
|
2019-04-03 06:49:32 +00:00
|
|
|
user_id: user_id,
|
2019-03-28 19:32:08 +00:00
|
|
|
score: self.score
|
|
|
|
};
|
|
|
|
|
|
|
|
// Remove any likes first
|
|
|
|
CommentLike::remove(&conn, &like_form).unwrap();
|
|
|
|
|
|
|
|
// Only add the like if the score isnt 0
|
|
|
|
if &like_form.score != &0 {
|
2019-04-03 20:59:37 +00:00
|
|
|
let _inserted_like = match CommentLike::like(&conn, &like_form) {
|
2019-03-28 19:32:08 +00:00
|
|
|
Ok(like) => like,
|
2019-04-03 20:59:37 +00:00
|
|
|
Err(_e) => {
|
2019-03-28 19:32:08 +00:00
|
|
|
return self.error("Couldn't like comment.");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
// Have to refetch the comment to get the current state
|
2019-04-03 20:59:37 +00:00
|
|
|
let liked_comment = CommentView::read(&conn, self.comment_id, Some(user_id)).unwrap();
|
2019-03-28 19:32:08 +00:00
|
|
|
|
|
|
|
let mut liked_comment_sent = liked_comment.clone();
|
|
|
|
liked_comment_sent.my_vote = None;
|
2019-04-03 20:59:37 +00:00
|
|
|
liked_comment_sent.user_id = None;
|
2019-03-28 19:32:08 +00:00
|
|
|
|
|
|
|
let like_out = serde_json::to_string(
|
2019-04-03 20:59:37 +00:00
|
|
|
&CommentResponse {
|
2019-03-28 19:32:08 +00:00
|
|
|
op: self.op_type().to_string(),
|
|
|
|
comment: liked_comment
|
|
|
|
}
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
let like_sent_out = serde_json::to_string(
|
2019-04-03 20:59:37 +00:00
|
|
|
&CommentResponse {
|
2019-03-28 19:32:08 +00:00
|
|
|
op: self.op_type().to_string(),
|
|
|
|
comment: liked_comment_sent
|
|
|
|
}
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
|
2019-04-03 23:01:20 +00:00
|
|
|
chat.send_room_message(self.post_id, &like_sent_out, addr);
|
2019-03-28 19:32:08 +00:00
|
|
|
|
2019-04-03 23:01:20 +00:00
|
|
|
like_out
|
2019-03-28 19:32:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-26 18:00:18 +00:00
|
|
|
|
2019-04-03 06:49:32 +00:00
|
|
|
impl Perform for GetPosts {
|
|
|
|
fn op_type(&self) -> UserOperation {
|
|
|
|
UserOperation::GetPosts
|
|
|
|
}
|
|
|
|
|
2019-04-03 20:59:37 +00:00
|
|
|
fn perform(&self, _chat: &mut ChatServer, _addr: usize) -> String {
|
2019-04-03 06:49:32 +00:00
|
|
|
|
|
|
|
let conn = establish_connection();
|
|
|
|
|
|
|
|
let user_id: Option<i32> = match &self.auth {
|
|
|
|
Some(auth) => {
|
|
|
|
match Claims::decode(&auth) {
|
|
|
|
Ok(claims) => {
|
|
|
|
let user_id = claims.claims.id;
|
|
|
|
Some(user_id)
|
|
|
|
}
|
2019-04-03 20:59:37 +00:00
|
|
|
Err(_e) => None
|
2019-04-03 06:49:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
None => None
|
|
|
|
};
|
|
|
|
|
2019-04-08 05:19:02 +00:00
|
|
|
let type_ = PostListingType::from_str(&self.type_).expect("listing type");
|
|
|
|
let sort = SortType::from_str(&self.sort).expect("listing sort");
|
2019-04-03 06:49:32 +00:00
|
|
|
|
2019-04-08 05:19:02 +00:00
|
|
|
let posts = match PostView::list(&conn, type_, &sort, self.community_id, None, user_id, self.limit) {
|
2019-04-03 06:49:32 +00:00
|
|
|
Ok(posts) => posts,
|
2019-04-03 20:59:37 +00:00
|
|
|
Err(_e) => {
|
|
|
|
eprintln!("{}", _e);
|
2019-04-03 06:49:32 +00:00
|
|
|
return self.error("Couldn't get posts");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Return the jwt
|
|
|
|
serde_json::to_string(
|
|
|
|
&GetPostsResponse {
|
|
|
|
op: self.op_type().to_string(),
|
|
|
|
posts: posts
|
|
|
|
}
|
|
|
|
)
|
|
|
|
.unwrap()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl Perform for CreatePostLike {
|
|
|
|
fn op_type(&self) -> UserOperation {
|
|
|
|
UserOperation::CreatePostLike
|
|
|
|
}
|
|
|
|
|
2019-04-03 20:59:37 +00:00
|
|
|
fn perform(&self, _chat: &mut ChatServer, _addr: usize) -> String {
|
2019-04-03 06:49:32 +00:00
|
|
|
|
|
|
|
let conn = establish_connection();
|
|
|
|
|
|
|
|
let claims = match Claims::decode(&self.auth) {
|
|
|
|
Ok(claims) => claims.claims,
|
2019-04-03 20:59:37 +00:00
|
|
|
Err(_e) => {
|
2019-04-03 06:49:32 +00:00
|
|
|
return self.error("Not logged in.");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
let user_id = claims.id;
|
|
|
|
|
|
|
|
let like_form = PostLikeForm {
|
|
|
|
post_id: self.post_id,
|
|
|
|
user_id: user_id,
|
|
|
|
score: self.score
|
|
|
|
};
|
|
|
|
|
|
|
|
// Remove any likes first
|
|
|
|
PostLike::remove(&conn, &like_form).unwrap();
|
|
|
|
|
|
|
|
// Only add the like if the score isnt 0
|
|
|
|
if &like_form.score != &0 {
|
2019-04-03 20:59:37 +00:00
|
|
|
let _inserted_like = match PostLike::like(&conn, &like_form) {
|
2019-04-03 06:49:32 +00:00
|
|
|
Ok(like) => like,
|
2019-04-03 20:59:37 +00:00
|
|
|
Err(_e) => {
|
2019-04-03 06:49:32 +00:00
|
|
|
return self.error("Couldn't like post.");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2019-04-03 23:01:20 +00:00
|
|
|
let post_view = match PostView::read(&conn, self.post_id, Some(user_id)) {
|
2019-04-03 06:49:32 +00:00
|
|
|
Ok(post) => post,
|
2019-04-03 20:59:37 +00:00
|
|
|
Err(_e) => {
|
2019-04-03 06:49:32 +00:00
|
|
|
return self.error("Couldn't find Post");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// just output the score
|
|
|
|
|
|
|
|
let like_out = serde_json::to_string(
|
|
|
|
&CreatePostLikeResponse {
|
|
|
|
op: self.op_type().to_string(),
|
|
|
|
post: post_view
|
|
|
|
}
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
|
2019-04-03 23:01:20 +00:00
|
|
|
like_out
|
2019-04-03 06:49:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-03 20:59:37 +00:00
|
|
|
impl Perform for EditPost {
|
|
|
|
fn op_type(&self) -> UserOperation {
|
|
|
|
UserOperation::EditPost
|
|
|
|
}
|
|
|
|
|
|
|
|
fn perform(&self, chat: &mut ChatServer, addr: usize) -> String {
|
|
|
|
|
|
|
|
let conn = establish_connection();
|
|
|
|
|
|
|
|
let claims = match Claims::decode(&self.auth) {
|
|
|
|
Ok(claims) => claims.claims,
|
|
|
|
Err(_e) => {
|
|
|
|
return self.error("Not logged in.");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
let user_id = claims.id;
|
|
|
|
|
2019-04-05 00:25:21 +00:00
|
|
|
// Verify its the creator
|
|
|
|
let orig_post = Post::read(&conn, self.edit_id).unwrap();
|
|
|
|
if user_id != orig_post.creator_id {
|
2019-04-05 06:26:38 +00:00
|
|
|
return self.error("Incorrect creator.");
|
2019-04-05 00:25:21 +00:00
|
|
|
}
|
|
|
|
|
2019-04-03 20:59:37 +00:00
|
|
|
let post_form = PostForm {
|
|
|
|
name: self.name.to_owned(),
|
|
|
|
url: self.url.to_owned(),
|
|
|
|
body: self.body.to_owned(),
|
|
|
|
creator_id: user_id,
|
|
|
|
community_id: self.community_id,
|
|
|
|
updated: Some(naive_now())
|
|
|
|
};
|
|
|
|
|
|
|
|
let _updated_post = match Post::update(&conn, self.edit_id, &post_form) {
|
|
|
|
Ok(post) => post,
|
|
|
|
Err(_e) => {
|
|
|
|
return self.error("Couldn't update Post");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-04-03 23:01:20 +00:00
|
|
|
let post_view = PostView::read(&conn, self.edit_id, Some(user_id)).unwrap();
|
2019-04-03 20:59:37 +00:00
|
|
|
|
|
|
|
let mut post_sent = post_view.clone();
|
|
|
|
post_sent.my_vote = None;
|
|
|
|
|
|
|
|
let post_out = serde_json::to_string(
|
|
|
|
&PostResponse {
|
|
|
|
op: self.op_type().to_string(),
|
|
|
|
post: post_view
|
|
|
|
}
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
let post_sent_out = serde_json::to_string(
|
|
|
|
&PostResponse {
|
|
|
|
op: self.op_type().to_string(),
|
|
|
|
post: post_sent
|
|
|
|
}
|
|
|
|
)
|
|
|
|
.unwrap();
|
2019-04-03 23:01:20 +00:00
|
|
|
|
2019-04-03 20:59:37 +00:00
|
|
|
chat.send_room_message(self.edit_id, &post_sent_out, addr);
|
|
|
|
|
|
|
|
post_out
|
|
|
|
}
|
|
|
|
}
|
2019-04-04 22:29:14 +00:00
|
|
|
|
|
|
|
impl Perform for EditCommunity {
|
|
|
|
fn op_type(&self) -> UserOperation {
|
|
|
|
UserOperation::EditCommunity
|
|
|
|
}
|
|
|
|
|
|
|
|
fn perform(&self, chat: &mut ChatServer, addr: usize) -> String {
|
|
|
|
|
|
|
|
let conn = establish_connection();
|
|
|
|
|
|
|
|
let claims = match Claims::decode(&self.auth) {
|
|
|
|
Ok(claims) => claims.claims,
|
|
|
|
Err(_e) => {
|
|
|
|
return self.error("Not logged in.");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
let user_id = claims.id;
|
|
|
|
|
2019-04-05 00:25:21 +00:00
|
|
|
|
|
|
|
// Verify its a mod
|
|
|
|
let moderator_view = CommunityModeratorView::for_community(&conn, self.edit_id).unwrap();
|
|
|
|
let mod_ids: Vec<i32> = moderator_view.into_iter().map(|m| m.user_id).collect();
|
|
|
|
if !mod_ids.contains(&user_id) {
|
2019-04-05 06:26:38 +00:00
|
|
|
return self.error("Incorrect creator.");
|
2019-04-05 00:25:21 +00:00
|
|
|
};
|
|
|
|
|
2019-04-04 22:29:14 +00:00
|
|
|
let community_form = CommunityForm {
|
|
|
|
name: self.name.to_owned(),
|
|
|
|
title: self.title.to_owned(),
|
|
|
|
description: self.description.to_owned(),
|
|
|
|
category_id: self.category_id.to_owned(),
|
|
|
|
creator_id: user_id,
|
|
|
|
updated: Some(naive_now())
|
|
|
|
};
|
|
|
|
|
|
|
|
let _updated_community = match Community::update(&conn, self.edit_id, &community_form) {
|
|
|
|
Ok(community) => community,
|
|
|
|
Err(_e) => {
|
|
|
|
return self.error("Couldn't update Community");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-04-05 06:26:38 +00:00
|
|
|
let community_view = CommunityView::read(&conn, self.edit_id, Some(user_id)).unwrap();
|
2019-04-04 22:29:14 +00:00
|
|
|
|
|
|
|
// Do the subscriber stuff here
|
|
|
|
// let mut community_sent = post_view.clone();
|
|
|
|
// community_sent.my_vote = None;
|
|
|
|
|
|
|
|
let community_out = serde_json::to_string(
|
|
|
|
&CommunityResponse {
|
|
|
|
op: self.op_type().to_string(),
|
|
|
|
community: community_view
|
|
|
|
}
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// let post_sent_out = serde_json::to_string(
|
|
|
|
// &PostResponse {
|
|
|
|
// op: self.op_type().to_string(),
|
|
|
|
// post: post_sent
|
|
|
|
// }
|
|
|
|
// )
|
|
|
|
// .unwrap();
|
|
|
|
|
|
|
|
chat.send_room_message(self.edit_id, &community_out, addr);
|
|
|
|
|
|
|
|
community_out
|
|
|
|
}
|
|
|
|
}
|
2019-04-05 06:26:38 +00:00
|
|
|
|
|
|
|
|
|
|
|
impl Perform for FollowCommunity {
|
|
|
|
fn op_type(&self) -> UserOperation {
|
|
|
|
UserOperation::FollowCommunity
|
|
|
|
}
|
|
|
|
|
|
|
|
fn perform(&self, _chat: &mut ChatServer, _addr: usize) -> String {
|
|
|
|
|
|
|
|
let conn = establish_connection();
|
|
|
|
|
|
|
|
let claims = match Claims::decode(&self.auth) {
|
|
|
|
Ok(claims) => claims.claims,
|
|
|
|
Err(_e) => {
|
|
|
|
return self.error("Not logged in.");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
let user_id = claims.id;
|
|
|
|
|
|
|
|
let community_follower_form = CommunityFollowerForm {
|
|
|
|
community_id: self.community_id,
|
|
|
|
user_id: user_id
|
|
|
|
};
|
|
|
|
|
|
|
|
if self.follow {
|
|
|
|
|
|
|
|
match CommunityFollower::follow(&conn, &community_follower_form) {
|
|
|
|
Ok(user) => user,
|
|
|
|
Err(_e) => {
|
|
|
|
return self.error("Community follower already exists.");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
} else {
|
|
|
|
match CommunityFollower::ignore(&conn, &community_follower_form) {
|
|
|
|
Ok(user) => user,
|
|
|
|
Err(_e) => {
|
|
|
|
return self.error("Community follower already exists.");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
let community_view = CommunityView::read(&conn, self.community_id, Some(user_id)).unwrap();
|
|
|
|
|
|
|
|
serde_json::to_string(
|
|
|
|
&CommunityResponse {
|
|
|
|
op: self.op_type().to_string(),
|
|
|
|
community: community_view
|
|
|
|
}
|
|
|
|
)
|
|
|
|
.unwrap()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-05 19:14:54 +00:00
|
|
|
impl Perform for GetFollowedCommunities {
|
|
|
|
fn op_type(&self) -> UserOperation {
|
|
|
|
UserOperation::GetFollowedCommunities
|
|
|
|
}
|
|
|
|
|
|
|
|
fn perform(&self, _chat: &mut ChatServer, _addr: usize) -> String {
|
|
|
|
|
|
|
|
let conn = establish_connection();
|
|
|
|
|
|
|
|
let claims = match Claims::decode(&self.auth) {
|
|
|
|
Ok(claims) => claims.claims,
|
|
|
|
Err(_e) => {
|
|
|
|
return self.error("Not logged in.");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
let user_id = claims.id;
|
|
|
|
|
|
|
|
let communities: Vec<CommunityFollowerView> = CommunityFollowerView::for_user(&conn, user_id).unwrap();
|
|
|
|
|
|
|
|
// Return the jwt
|
|
|
|
serde_json::to_string(
|
|
|
|
&GetFollowedCommunitiesResponse {
|
|
|
|
op: self.op_type().to_string(),
|
|
|
|
communities: communities
|
|
|
|
}
|
|
|
|
)
|
|
|
|
.unwrap()
|
|
|
|
}
|
|
|
|
}
|
2019-04-05 06:26:38 +00:00
|
|
|
|
2019-04-08 05:19:02 +00:00
|
|
|
impl Perform for GetUserDetails {
|
|
|
|
fn op_type(&self) -> UserOperation {
|
|
|
|
UserOperation::GetUserDetails
|
|
|
|
}
|
|
|
|
|
|
|
|
fn perform(&self, _chat: &mut ChatServer, _addr: usize) -> String {
|
|
|
|
|
|
|
|
let conn = establish_connection();
|
|
|
|
|
|
|
|
let user_id: Option<i32> = match &self.auth {
|
|
|
|
Some(auth) => {
|
|
|
|
match Claims::decode(&auth) {
|
|
|
|
Ok(claims) => {
|
|
|
|
let user_id = claims.claims.id;
|
|
|
|
Some(user_id)
|
|
|
|
}
|
|
|
|
Err(_e) => None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
None => None
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
//TODO add save
|
|
|
|
let sort = SortType::from_str(&self.sort).expect("listing sort");
|
|
|
|
|
|
|
|
let user_view = UserView::read(&conn, self.user_id).unwrap();
|
|
|
|
let posts = PostView::list(&conn, PostListingType::All, &sort, self.community_id, Some(self.user_id), user_id, self.limit).unwrap();
|
|
|
|
let comments = CommentView::list(&conn, &sort, None, Some(self.user_id), user_id, self.limit).unwrap();
|
|
|
|
let follows = CommunityFollowerView::for_user(&conn, self.user_id).unwrap();
|
|
|
|
let moderates = CommunityModeratorView::for_user(&conn, self.user_id).unwrap();
|
|
|
|
|
|
|
|
// Return the jwt
|
|
|
|
serde_json::to_string(
|
|
|
|
&GetUserDetailsResponse {
|
|
|
|
op: self.op_type().to_string(),
|
|
|
|
user: user_view,
|
|
|
|
follows: follows,
|
|
|
|
moderates: moderates,
|
|
|
|
comments: comments,
|
|
|
|
posts: posts,
|
|
|
|
saved_posts: Vec::new(),
|
|
|
|
saved_comments: Vec::new(),
|
|
|
|
}
|
|
|
|
)
|
|
|
|
.unwrap()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-25 03:51:27 +00:00
|
|
|
// impl Handler<Login> for ChatServer {
|
|
|
|
|
|
|
|
// type Result = MessageResult<Login>;
|
|
|
|
// fn handle(&mut self, msg: Login, _: &mut Context<Self>) -> Self::Result {
|
|
|
|
|
|
|
|
// let conn = establish_connection();
|
|
|
|
|
|
|
|
// // Fetch that username / email
|
|
|
|
// let user: User_ = match User_::find_by_email_or_username(&conn, &msg.username_or_email) {
|
|
|
|
// Ok(user) => user,
|
2019-04-03 20:59:37 +00:00
|
|
|
// Err(_e) => return MessageResult(
|
2019-03-25 03:51:27 +00:00
|
|
|
// Err(
|
|
|
|
// ErrorMessage {
|
|
|
|
// op: UserOperation::Login.to_string(),
|
|
|
|
// error: "Couldn't find that username or email".to_string()
|
|
|
|
// }
|
|
|
|
// )
|
|
|
|
// )
|
|
|
|
// };
|
|
|
|
|
|
|
|
// // Verify the password
|
|
|
|
// let valid: bool = verify(&msg.password, &user.password_encrypted).unwrap_or(false);
|
|
|
|
// if !valid {
|
|
|
|
// return MessageResult(
|
|
|
|
// Err(
|
|
|
|
// ErrorMessage {
|
|
|
|
// op: UserOperation::Login.to_string(),
|
|
|
|
// error: "Password incorrect".to_string()
|
|
|
|
// }
|
|
|
|
// )
|
|
|
|
// )
|
|
|
|
// }
|
|
|
|
|
|
|
|
// // Return the jwt
|
|
|
|
// MessageResult(
|
|
|
|
// Ok(
|
|
|
|
// LoginResponse {
|
|
|
|
// op: UserOperation::Login.to_string(),
|
|
|
|
// jwt: user.jwt()
|
|
|
|
// }
|
|
|
|
// )
|
|
|
|
// )
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
// impl Handler<Register> for ChatServer {
|
|
|
|
|
|
|
|
// type Result = MessageResult<Register>;
|
|
|
|
// fn handle(&mut self, msg: Register, _: &mut Context<Self>) -> Self::Result {
|
|
|
|
|
|
|
|
// let conn = establish_connection();
|
|
|
|
|
|
|
|
// // Make sure passwords match
|
|
|
|
// if msg.password != msg.password_verify {
|
|
|
|
// return MessageResult(
|
|
|
|
// Err(
|
|
|
|
// ErrorMessage {
|
|
|
|
// op: UserOperation::Register.to_string(),
|
|
|
|
// error: "Passwords do not match.".to_string()
|
|
|
|
// }
|
|
|
|
// )
|
|
|
|
// );
|
|
|
|
// }
|
|
|
|
|
|
|
|
// // Register the new user
|
|
|
|
// let user_form = UserForm {
|
|
|
|
// name: msg.username,
|
|
|
|
// email: msg.email,
|
|
|
|
// password_encrypted: msg.password,
|
|
|
|
// preferred_username: None,
|
|
|
|
// updated: None
|
|
|
|
// };
|
|
|
|
|
|
|
|
// // Create the user
|
|
|
|
// let inserted_user = match User_::create(&conn, &user_form) {
|
|
|
|
// Ok(user) => user,
|
2019-04-03 20:59:37 +00:00
|
|
|
// Err(_e) => return MessageResult(
|
2019-03-25 03:51:27 +00:00
|
|
|
// Err(
|
|
|
|
// ErrorMessage {
|
|
|
|
// op: UserOperation::Register.to_string(),
|
|
|
|
// error: "User already exists.".to_string() // overwrite the diesel error
|
|
|
|
// }
|
|
|
|
// )
|
|
|
|
// )
|
|
|
|
// };
|
|
|
|
|
|
|
|
// // Return the jwt
|
|
|
|
// MessageResult(
|
|
|
|
// Ok(
|
|
|
|
// LoginResponse {
|
|
|
|
// op: UserOperation::Register.to_string(),
|
|
|
|
// jwt: inserted_user.jwt()
|
|
|
|
// }
|
|
|
|
// )
|
|
|
|
// )
|
|
|
|
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
// impl Handler<CreateCommunity> for ChatServer {
|
|
|
|
|
|
|
|
// type Result = MessageResult<CreateCommunity>;
|
|
|
|
|
|
|
|
// fn handle(&mut self, msg: CreateCommunity, _: &mut Context<Self>) -> Self::Result {
|
|
|
|
// let conn = establish_connection();
|
|
|
|
|
|
|
|
// let user_id = Claims::decode(&msg.auth).id;
|
|
|
|
|
|
|
|
// let community_form = CommunityForm {
|
|
|
|
// name: msg.name,
|
|
|
|
// updated: None
|
|
|
|
// };
|
|
|
|
|
|
|
|
// let community = match Community::create(&conn, &community_form) {
|
|
|
|
// Ok(community) => community,
|
2019-04-03 20:59:37 +00:00
|
|
|
// Err(_e) => return MessageResult(
|
2019-03-25 03:51:27 +00:00
|
|
|
// Err(
|
|
|
|
// ErrorMessage {
|
|
|
|
// op: UserOperation::CreateCommunity.to_string(),
|
|
|
|
// error: "Community already exists.".to_string() // overwrite the diesel error
|
|
|
|
// }
|
|
|
|
// )
|
|
|
|
// )
|
|
|
|
// };
|
2019-04-03 23:01:20 +00:00
|
|
|
|
2019-03-25 03:51:27 +00:00
|
|
|
// MessageResult(
|
|
|
|
// Ok(
|
2019-04-04 22:29:14 +00:00
|
|
|
// CommunityResponse {
|
2019-03-25 03:51:27 +00:00
|
|
|
// op: UserOperation::CreateCommunity.to_string(),
|
|
|
|
// community: community
|
|
|
|
// }
|
|
|
|
// )
|
|
|
|
// )
|
|
|
|
// }
|
|
|
|
// }
|
2019-03-26 18:00:18 +00:00
|
|
|
//
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// /// Handler for `ListRooms` message.
|
|
|
|
// impl Handler<ListRooms> for ChatServer {
|
|
|
|
// type Result = MessageResult<ListRooms>;
|
|
|
|
|
|
|
|
// fn handle(&mut self, _: ListRooms, _: &mut Context<Self>) -> Self::Result {
|
|
|
|
// let mut rooms = Vec::new();
|
|
|
|
|
|
|
|
// for key in self.rooms.keys() {
|
|
|
|
// rooms.push(key.to_owned())
|
|
|
|
// }
|
|
|
|
|
|
|
|
// MessageResult(rooms)
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
// /// Join room, send disconnect message to old room
|
|
|
|
// /// send join message to new room
|
|
|
|
// impl Handler<Join> for ChatServer {
|
|
|
|
// type Result = ();
|
|
|
|
|
|
|
|
// fn handle(&mut self, msg: Join, _: &mut Context<Self>) {
|
|
|
|
// let Join { id, name } = msg;
|
|
|
|
// let mut rooms = Vec::new();
|
|
|
|
|
|
|
|
// // remove session from all rooms
|
|
|
|
// for (n, sessions) in &mut self.rooms {
|
|
|
|
// if sessions.remove(&id) {
|
|
|
|
// rooms.push(n.to_owned());
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// // send message to other users
|
|
|
|
// for room in rooms {
|
|
|
|
// self.send_room_message(&room, "Someone disconnected", 0);
|
|
|
|
// }
|
|
|
|
|
|
|
|
// if self.rooms.get_mut(&name).is_none() {
|
|
|
|
// self.rooms.insert(name.clone(), HashSet::new());
|
|
|
|
// }
|
|
|
|
// self.send_room_message(&name, "Someone connected", id);
|
|
|
|
// self.rooms.get_mut(&name).unwrap().insert(id);
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|