forked from jmug/stoatchat
Start work on notifications from client, cargo fmt
This commit is contained in:
@@ -1,6 +1,9 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
use crate::{
|
||||||
use crate::{database::get_collection, util::result::{Error, Result}};
|
database::get_collection,
|
||||||
|
util::result::{Error, Result},
|
||||||
|
};
|
||||||
use mongodb::bson::to_document;
|
use mongodb::bson::to_document;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/*#[derive(Serialize, Deserialize, Debug, Clone)]
|
/*#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
pub struct LastMessage {
|
pub struct LastMessage {
|
||||||
@@ -38,7 +41,7 @@ pub enum Channel {
|
|||||||
SavedMessages {
|
SavedMessages {
|
||||||
#[serde(rename = "_id")]
|
#[serde(rename = "_id")]
|
||||||
id: String,
|
id: String,
|
||||||
user: String
|
user: String,
|
||||||
},
|
},
|
||||||
DirectMessage {
|
DirectMessage {
|
||||||
#[serde(rename = "_id")]
|
#[serde(rename = "_id")]
|
||||||
@@ -53,19 +56,24 @@ pub enum Channel {
|
|||||||
owner: String,
|
owner: String,
|
||||||
description: String,
|
description: String,
|
||||||
recipients: Vec<String>,
|
recipients: Vec<String>,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Channel {
|
impl Channel {
|
||||||
pub async fn save(&self) -> Result<()> {
|
pub async fn save(&self) -> Result<()> {
|
||||||
get_collection("channels")
|
get_collection("channels")
|
||||||
.insert_one(
|
.insert_one(
|
||||||
to_document(&self)
|
to_document(&self).map_err(|_| Error::DatabaseError {
|
||||||
.map_err(|_| Error::DatabaseError { operation: "to_bson", with: "channel" })?,
|
operation: "to_bson",
|
||||||
None
|
with: "channel",
|
||||||
|
})?,
|
||||||
|
None,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.map_err(|_| Error::DatabaseError { operation: "insert_one", with: "channel" })?;
|
.map_err(|_| Error::DatabaseError {
|
||||||
|
operation: "insert_one",
|
||||||
|
with: "channel",
|
||||||
|
})?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
mod channel;
|
mod channel;
|
||||||
mod message;
|
|
||||||
mod guild;
|
mod guild;
|
||||||
|
mod message;
|
||||||
mod user;
|
mod user;
|
||||||
|
|
||||||
pub use channel::*;
|
pub use channel::*;
|
||||||
pub use message::*;
|
|
||||||
pub use guild::*;
|
pub use guild::*;
|
||||||
|
pub use message::*;
|
||||||
pub use user::*;
|
pub use user::*;
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
|
use crate::database::get_collection;
|
||||||
|
use crate::database::guards::reference::Ref;
|
||||||
use mongodb::bson::{doc, from_bson, Bson};
|
use mongodb::bson::{doc, from_bson, Bson};
|
||||||
use rauth::auth::Session;
|
use rauth::auth::Session;
|
||||||
use rocket::http::Status;
|
use rocket::http::Status;
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use crate::database::guards::reference::Ref;
|
|
||||||
use crate::database::get_collection;
|
|
||||||
use rocket::request::{self, FromRequest, Outcome, Request};
|
use rocket::request::{self, FromRequest, Outcome, Request};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
pub enum RelationshipStatus {
|
pub enum RelationshipStatus {
|
||||||
@@ -14,7 +14,7 @@ pub enum RelationshipStatus {
|
|||||||
Outgoing,
|
Outgoing,
|
||||||
Incoming,
|
Incoming,
|
||||||
Blocked,
|
Blocked,
|
||||||
BlockedOther
|
BlockedOther,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
@@ -44,24 +44,29 @@ impl<'a, 'r> FromRequest<'a, 'r> for User {
|
|||||||
.find_one(
|
.find_one(
|
||||||
doc! {
|
doc! {
|
||||||
"_id": &session.user_id
|
"_id": &session.user_id
|
||||||
}, None
|
},
|
||||||
|
None,
|
||||||
)
|
)
|
||||||
.await {
|
.await
|
||||||
|
{
|
||||||
if let Some(doc) = result {
|
if let Some(doc) = result {
|
||||||
Outcome::Success(
|
Outcome::Success(from_bson(Bson::Document(doc)).unwrap())
|
||||||
from_bson(Bson::Document(doc)).unwrap()
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
Outcome::Failure((Status::Forbidden, rauth::util::Error::InvalidSession))
|
Outcome::Failure((Status::Forbidden, rauth::util::Error::InvalidSession))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Outcome::Failure((Status::InternalServerError, rauth::util::Error::DatabaseError))
|
Outcome::Failure((
|
||||||
|
Status::InternalServerError,
|
||||||
|
rauth::util::Error::DatabaseError,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl User {
|
impl User {
|
||||||
pub fn as_ref(&self) -> Ref {
|
pub fn as_ref(&self) -> Ref {
|
||||||
Ref { id: self.id.to_string() }
|
Ref {
|
||||||
|
id: self.id.to_string(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
pub mod user;
|
|
||||||
pub mod reference;
|
pub mod reference;
|
||||||
|
pub mod user;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// ! FIXME
|
// ! FIXME
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
use mongodb::bson::{doc, from_bson, Bson};
|
|
||||||
use crate::util::result::{Error, Result};
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use crate::database::get_collection;
|
|
||||||
use crate::database::entities::*;
|
use crate::database::entities::*;
|
||||||
use rocket::request::FromParam;
|
use crate::database::get_collection;
|
||||||
|
use crate::util::result::{Error, Result};
|
||||||
|
use mongodb::bson::{doc, from_bson, Bson};
|
||||||
use rocket::http::RawStr;
|
use rocket::http::RawStr;
|
||||||
|
use rocket::request::FromParam;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use validator::Validate;
|
use validator::Validate;
|
||||||
|
|
||||||
#[derive(Validate, Serialize, Deserialize)]
|
#[derive(Validate, Serialize, Deserialize)]
|
||||||
@@ -24,15 +24,20 @@ impl Ref {
|
|||||||
doc! {
|
doc! {
|
||||||
"_id": &self.id
|
"_id": &self.id
|
||||||
},
|
},
|
||||||
None
|
None,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.map_err(|_| Error::DatabaseError { operation: "find_one", with: "user" })?
|
.map_err(|_| Error::DatabaseError {
|
||||||
|
operation: "find_one",
|
||||||
|
with: "user",
|
||||||
|
})?
|
||||||
.ok_or_else(|| Error::UnknownUser)?;
|
.ok_or_else(|| Error::UnknownUser)?;
|
||||||
|
|
||||||
Ok(
|
Ok(
|
||||||
from_bson(Bson::Document(doc))
|
from_bson(Bson::Document(doc)).map_err(|_| Error::DatabaseError {
|
||||||
.map_err(|_| Error::DatabaseError { operation: "from_bson", with: "user" })?
|
operation: "from_bson",
|
||||||
|
with: "user",
|
||||||
|
})?,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
|
|||||||
@@ -10,28 +10,28 @@ pub async fn create_database() {
|
|||||||
let db = get_db();
|
let db = get_db();
|
||||||
|
|
||||||
db.create_collection("users", None)
|
db.create_collection("users", None)
|
||||||
.await
|
.await
|
||||||
.expect("Failed to create users collection.");
|
.expect("Failed to create users collection.");
|
||||||
|
|
||||||
db.create_collection("channels", None)
|
db.create_collection("channels", None)
|
||||||
.await
|
.await
|
||||||
.expect("Failed to create channels collection.");
|
.expect("Failed to create channels collection.");
|
||||||
|
|
||||||
db.create_collection("guilds", None)
|
db.create_collection("guilds", None)
|
||||||
.await
|
.await
|
||||||
.expect("Failed to create guilds collection.");
|
.expect("Failed to create guilds collection.");
|
||||||
|
|
||||||
db.create_collection("members", None)
|
db.create_collection("members", None)
|
||||||
.await
|
.await
|
||||||
.expect("Failed to create members collection.");
|
.expect("Failed to create members collection.");
|
||||||
|
|
||||||
db.create_collection("messages", None)
|
db.create_collection("messages", None)
|
||||||
.await
|
.await
|
||||||
.expect("Failed to create messages collection.");
|
.expect("Failed to create messages collection.");
|
||||||
|
|
||||||
db.create_collection("migrations", None)
|
db.create_collection("migrations", None)
|
||||||
.await
|
.await
|
||||||
.expect("Failed to create migrations collection.");
|
.expect("Failed to create migrations collection.");
|
||||||
|
|
||||||
db.create_collection(
|
db.create_collection(
|
||||||
"pubsub",
|
"pubsub",
|
||||||
@@ -60,21 +60,21 @@ pub async fn create_database() {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
None
|
None,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.expect("Failed to create username index.");
|
.expect("Failed to create username index.");
|
||||||
|
|
||||||
db.collection("migrations")
|
db.collection("migrations")
|
||||||
.insert_one(
|
.insert_one(
|
||||||
doc! {
|
doc! {
|
||||||
"_id": 0,
|
"_id": 0,
|
||||||
"revision": LATEST_REVISION
|
"revision": LATEST_REVISION
|
||||||
},
|
},
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.expect("Failed to save migration info.");
|
.expect("Failed to save migration info.");
|
||||||
|
|
||||||
info!("Created database.");
|
info!("Created database.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
use super::super::{get_db, get_collection};
|
use super::super::{get_collection, get_db};
|
||||||
|
|
||||||
|
use crate::rocket::futures::StreamExt;
|
||||||
use log::info;
|
use log::info;
|
||||||
|
use mongodb::bson::{doc, from_bson, Bson};
|
||||||
use mongodb::options::FindOptions;
|
use mongodb::options::FindOptions;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use crate::rocket::futures::StreamExt;
|
|
||||||
use mongodb::bson::{doc, from_bson, Bson};
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct MigrationInfo {
|
struct MigrationInfo {
|
||||||
@@ -124,27 +124,28 @@ pub async fn run_migrations(revision: i32) -> i32 {
|
|||||||
if revision <= 2 {
|
if revision <= 2 {
|
||||||
info!("Running migration [revision 2]: Add username index to users.");
|
info!("Running migration [revision 2]: Add username index to users.");
|
||||||
|
|
||||||
get_db().run_command(
|
get_db()
|
||||||
doc! {
|
.run_command(
|
||||||
"createIndexes": "users",
|
doc! {
|
||||||
"indexes": [
|
"createIndexes": "users",
|
||||||
{
|
"indexes": [
|
||||||
"key": {
|
{
|
||||||
"username": 1
|
"key": {
|
||||||
},
|
"username": 1
|
||||||
"name": "username",
|
},
|
||||||
"unique": true,
|
"name": "username",
|
||||||
"collation": {
|
"unique": true,
|
||||||
"locale": "en",
|
"collation": {
|
||||||
"strength": 2
|
"locale": "en",
|
||||||
|
"strength": 2
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
]
|
||||||
]
|
},
|
||||||
},
|
None,
|
||||||
None
|
)
|
||||||
)
|
.await
|
||||||
.await
|
.expect("Failed to create username index.");
|
||||||
.expect("Failed to create username index.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reminder to update LATEST_REVISION when adding new migrations.
|
// Reminder to update LATEST_REVISION when adding new migrations.
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ pub fn get_collection(collection: &str) -> Collection {
|
|||||||
get_db().collection(collection)
|
get_db().collection(collection)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod permissions;
|
|
||||||
pub mod migrations;
|
|
||||||
pub mod entities;
|
pub mod entities;
|
||||||
pub mod guards;
|
pub mod guards;
|
||||||
|
pub mod migrations;
|
||||||
|
pub mod permissions;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use std::ops;
|
|||||||
pub enum UserPermission {
|
pub enum UserPermission {
|
||||||
Access = 1,
|
Access = 1,
|
||||||
SendMessage = 2,
|
SendMessage = 2,
|
||||||
Invite = 4
|
Invite = 4,
|
||||||
}
|
}
|
||||||
|
|
||||||
bitfield! {
|
bitfield! {
|
||||||
@@ -40,9 +40,7 @@ pub fn get_relationship(a: &User, b: &Ref) -> RelationshipStatus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(relations) = &a.relations {
|
if let Some(relations) = &a.relations {
|
||||||
if let Some(relationship) = relations
|
if let Some(relationship) = relations.iter().find(|x| x.id == b.id) {
|
||||||
.iter()
|
|
||||||
.find(|x| x.id == b.id) {
|
|
||||||
return relationship.status.clone();
|
return relationship.status.clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
11
src/main.rs
11
src/main.rs
@@ -13,15 +13,15 @@ extern crate impl_ops;
|
|||||||
extern crate bitfield;
|
extern crate bitfield;
|
||||||
extern crate ctrlc;
|
extern crate ctrlc;
|
||||||
|
|
||||||
pub mod notifications;
|
|
||||||
pub mod database;
|
pub mod database;
|
||||||
|
pub mod notifications;
|
||||||
pub mod routes;
|
pub mod routes;
|
||||||
pub mod util;
|
pub mod util;
|
||||||
|
|
||||||
use rauth;
|
|
||||||
use log::info;
|
|
||||||
use futures::join;
|
|
||||||
use async_std::task;
|
use async_std::task;
|
||||||
|
use futures::join;
|
||||||
|
use log::info;
|
||||||
|
use rauth;
|
||||||
use rocket_cors::AllowedOrigins;
|
use rocket_cors::AllowedOrigins;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@@ -41,7 +41,8 @@ async fn entry() {
|
|||||||
ctrlc::set_handler(move || {
|
ctrlc::set_handler(move || {
|
||||||
// Force ungraceful exit to avoid hang.
|
// Force ungraceful exit to avoid hang.
|
||||||
std::process::exit(0);
|
std::process::exit(0);
|
||||||
}).expect("Error setting Ctrl-C handler");
|
})
|
||||||
|
.expect("Error setting Ctrl-C handler");
|
||||||
|
|
||||||
join!(
|
join!(
|
||||||
launch_web(),
|
launch_web(),
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use rauth::auth::Session;
|
use rauth::auth::Session;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use snafu::Snafu;
|
use snafu::Snafu;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Snafu)]
|
#[derive(Serialize, Deserialize, Debug, Snafu)]
|
||||||
@@ -15,7 +15,7 @@ pub enum WebSocketError {
|
|||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
#[serde(tag = "type")]
|
#[serde(tag = "type")]
|
||||||
pub enum ServerboundNotification {
|
pub enum ServerboundNotification {
|
||||||
Authenticate(Session)
|
Authenticate(Session),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
@@ -78,10 +78,9 @@ pub enum ClientboundNotification {
|
|||||||
GuildDelete {
|
GuildDelete {
|
||||||
id: String,
|
id: String,
|
||||||
},*/
|
},*/
|
||||||
|
|
||||||
UserRelationship {
|
UserRelationship {
|
||||||
id: String,
|
id: String,
|
||||||
user: String,
|
user: String,
|
||||||
status: i32,
|
status: i32,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
use super::events::ClientboundNotification;
|
use super::events::ClientboundNotification;
|
||||||
use crate::database::get_collection;
|
use crate::database::get_collection;
|
||||||
|
|
||||||
|
use futures::FutureExt;
|
||||||
use hive_pubsub::backend::mongo::MongodbPubSub;
|
use hive_pubsub::backend::mongo::MongodbPubSub;
|
||||||
use hive_pubsub::PubSub;
|
use hive_pubsub::PubSub;
|
||||||
|
use log::{debug, error};
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
use serde_json::to_string;
|
use serde_json::to_string;
|
||||||
use futures::FutureExt;
|
|
||||||
use log::{error, debug};
|
|
||||||
|
|
||||||
static HIVE: OnceCell<MongodbPubSub<String, String, ClientboundNotification>> = OnceCell::new();
|
static HIVE: OnceCell<MongodbPubSub<String, String, ClientboundNotification>> = OnceCell::new();
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
pub mod websocket;
|
|
||||||
pub mod events;
|
pub mod events;
|
||||||
pub mod hive;
|
pub mod hive;
|
||||||
|
pub mod websocket;
|
||||||
|
|||||||
@@ -1,21 +1,26 @@
|
|||||||
use crate::util::variables::WS_HOST;
|
use crate::{database::entities::User, util::variables::WS_HOST};
|
||||||
|
|
||||||
use log::info;
|
|
||||||
use ulid::Ulid;
|
|
||||||
use async_std::task;
|
|
||||||
use futures::prelude::*;
|
|
||||||
use std::str::from_utf8;
|
|
||||||
use std::sync::{Arc, RwLock};
|
|
||||||
use many_to_many::ManyToMany;
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use futures::stream::SplitSink;
|
|
||||||
use async_tungstenite::WebSocketStream;
|
|
||||||
use async_tungstenite::tungstenite::Message;
|
|
||||||
use async_std::net::{TcpListener, TcpStream};
|
use async_std::net::{TcpListener, TcpStream};
|
||||||
|
use async_std::task;
|
||||||
|
use async_tungstenite::tungstenite::Message;
|
||||||
|
use futures::channel::mpsc::{unbounded, UnboundedSender};
|
||||||
|
use futures::{pin_mut, prelude::*};
|
||||||
|
use log::info;
|
||||||
|
use many_to_many::ManyToMany;
|
||||||
|
use rauth::auth::Session;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::net::SocketAddr;
|
||||||
|
use std::str::from_utf8;
|
||||||
|
use std::sync::{Arc, Mutex, RwLock};
|
||||||
|
use ulid::Ulid;
|
||||||
|
|
||||||
|
use super::events::ServerboundNotification;
|
||||||
|
|
||||||
|
type Tx = UnboundedSender<Message>;
|
||||||
|
type PeerMap = Arc<Mutex<HashMap<SocketAddr, Tx>>>;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref CONNECTIONS: Arc<RwLock<HashMap<String, SplitSink<WebSocketStream<TcpStream>, Message>>>> =
|
static ref CONNECTIONS: PeerMap = Arc::new(Mutex::new(HashMap::new()));
|
||||||
Arc::new(RwLock::new(HashMap::new()));
|
|
||||||
static ref USERS: Arc<RwLock<ManyToMany<String, String>>> =
|
static ref USERS: Arc<RwLock<ManyToMany<String, String>>> =
|
||||||
Arc::new(RwLock::new(ManyToMany::new()));
|
Arc::new(RwLock::new(ManyToMany::new()));
|
||||||
}
|
}
|
||||||
@@ -31,27 +36,41 @@ pub async fn launch_server() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn accept(stream: TcpStream) {
|
async fn accept(stream: TcpStream) {
|
||||||
let addr = stream.peer_addr().expect("Connected streams should have a peer address.");
|
let addr = stream
|
||||||
|
.peer_addr()
|
||||||
|
.expect("Connected streams should have a peer address.");
|
||||||
let ws_stream = async_tungstenite::accept_async(stream)
|
let ws_stream = async_tungstenite::accept_async(stream)
|
||||||
.await
|
.await
|
||||||
.expect("Error during websocket handshake.");
|
.expect("Error during websocket handshake.");
|
||||||
|
|
||||||
info!("User established WebSocket connection from {}.", addr);
|
info!("User established WebSocket connection from {}.", &addr);
|
||||||
|
|
||||||
let id = Ulid::new().to_string();
|
let id = Ulid::new().to_string();
|
||||||
let (write, read) = ws_stream.split();
|
let (write, read) = ws_stream.split();
|
||||||
|
|
||||||
CONNECTIONS
|
let (tx, rx) = unbounded();
|
||||||
.write()
|
CONNECTIONS.lock().unwrap().insert(addr, tx);
|
||||||
.unwrap()
|
|
||||||
.insert(id, write);
|
|
||||||
|
|
||||||
read
|
let session: Option<Session> = None;
|
||||||
.for_each(|message| async {
|
let user: Option<User> = None;
|
||||||
let data = message.unwrap().into_data();
|
|
||||||
// if you mess with the data, you get the bazooki
|
let fwd = rx.map(Ok).forward(write);
|
||||||
let string = from_utf8(&data).unwrap();
|
let reading = read.for_each(|message| async {
|
||||||
println!("{}", string);
|
let data = message.unwrap().into_data();
|
||||||
})
|
// if you mess with the data, you get the bazooki
|
||||||
.await;
|
let string = from_utf8(&data).unwrap();
|
||||||
|
|
||||||
|
if let Ok(notification) = serde_json::from_str::<ServerboundNotification>(string) {
|
||||||
|
match notification {
|
||||||
|
ServerboundNotification::Authenticate(a) => {
|
||||||
|
dbg!(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
pin_mut!(fwd, reading);
|
||||||
|
future::select(fwd, reading).await;
|
||||||
|
|
||||||
|
println!("User {} disconnected.", &addr);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use rocket::Route;
|
use rocket::Route;
|
||||||
|
|
||||||
pub fn routes() -> Vec<Route> {
|
pub fn routes() -> Vec<Route> {
|
||||||
routes! []
|
routes![]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use rocket::Route;
|
use rocket::Route;
|
||||||
|
|
||||||
pub fn routes() -> Vec<Route> {
|
pub fn routes() -> Vec<Route> {
|
||||||
routes! []
|
routes![]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,11 @@ pub use rocket::http::Status;
|
|||||||
pub use rocket::response::Redirect;
|
pub use rocket::response::Redirect;
|
||||||
use rocket::Rocket;
|
use rocket::Rocket;
|
||||||
|
|
||||||
mod root;
|
mod channels;
|
||||||
mod users;
|
|
||||||
mod guild;
|
mod guild;
|
||||||
mod onboard;
|
mod onboard;
|
||||||
mod channels;
|
mod root;
|
||||||
|
mod users;
|
||||||
|
|
||||||
pub fn mount(rocket: Rocket) -> Rocket {
|
pub fn mount(rocket: Rocket) -> Rocket {
|
||||||
rocket
|
rocket
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
use mongodb::options::{Collation, FindOneOptions};
|
|
||||||
use crate::util::result::{Error, Result};
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use crate::database::entities::User;
|
use crate::database::entities::User;
|
||||||
use crate::database::get_collection;
|
use crate::database::get_collection;
|
||||||
use rocket_contrib::json::Json;
|
use crate::util::result::{Error, Result};
|
||||||
use rauth::auth::Session;
|
|
||||||
use validator::Validate;
|
|
||||||
use mongodb::bson::doc;
|
use mongodb::bson::doc;
|
||||||
|
use mongodb::options::{Collation, FindOneOptions};
|
||||||
|
use rauth::auth::Session;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
use rocket_contrib::json::Json;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use validator::Validate;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref RE_USERNAME: Regex = Regex::new(r"^[a-zA-Z0-9-_]+$").unwrap();
|
static ref RE_USERNAME: Regex = Regex::new(r"^[a-zA-Z0-9-_]+$").unwrap();
|
||||||
@@ -16,7 +16,7 @@ lazy_static! {
|
|||||||
#[derive(Validate, Serialize, Deserialize)]
|
#[derive(Validate, Serialize, Deserialize)]
|
||||||
pub struct Data {
|
pub struct Data {
|
||||||
#[validate(length(min = 2, max = 32), regex = "RE_USERNAME")]
|
#[validate(length(min = 2, max = 32), regex = "RE_USERNAME")]
|
||||||
username: String
|
username: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/complete", data = "<data>")]
|
#[post("/complete", data = "<data>")]
|
||||||
@@ -29,17 +29,22 @@ pub async fn req(session: Session, user: Option<User>, data: Json<Data>) -> Resu
|
|||||||
.map_err(|error| Error::FailedValidation { error })?;
|
.map_err(|error| Error::FailedValidation { error })?;
|
||||||
|
|
||||||
let col = get_collection("users");
|
let col = get_collection("users");
|
||||||
if col.find_one(
|
if col
|
||||||
doc! {
|
.find_one(
|
||||||
"username": &data.username
|
doc! {
|
||||||
},
|
"username": &data.username
|
||||||
FindOneOptions::builder()
|
},
|
||||||
.collation(Collation::builder().locale("en").strength(2).build())
|
FindOneOptions::builder()
|
||||||
.build()
|
.collation(Collation::builder().locale("en").strength(2).build())
|
||||||
)
|
.build(),
|
||||||
.await
|
)
|
||||||
.map_err(|_| Error::DatabaseError { operation: "find_one", with: "user" })?
|
.await
|
||||||
.is_some() {
|
.map_err(|_| Error::DatabaseError {
|
||||||
|
operation: "find_one",
|
||||||
|
with: "user",
|
||||||
|
})?
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
Err(Error::UsernameTaken)?
|
Err(Error::UsernameTaken)?
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,10 +53,13 @@ pub async fn req(session: Session, user: Option<User>, data: Json<Data>) -> Resu
|
|||||||
"_id": session.user_id,
|
"_id": session.user_id,
|
||||||
"username": &data.username
|
"username": &data.username
|
||||||
},
|
},
|
||||||
None
|
None,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.map_err(|_| Error::DatabaseError { operation: "insert_one", with: "user" })?;
|
.map_err(|_| Error::DatabaseError {
|
||||||
|
operation: "insert_one",
|
||||||
|
with: "user",
|
||||||
|
})?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use rocket_contrib::json::JsonValue;
|
|
||||||
use crate::database::entities::User;
|
use crate::database::entities::User;
|
||||||
use rauth::auth::Session;
|
use rauth::auth::Session;
|
||||||
|
use rocket_contrib::json::JsonValue;
|
||||||
|
|
||||||
#[get("/hello")]
|
#[get("/hello")]
|
||||||
pub async fn req(_session: Session, user: Option<User>) -> JsonValue {
|
pub async fn req(_session: Session, user: Option<User>) -> JsonValue {
|
||||||
|
|||||||
@@ -1,11 +1,8 @@
|
|||||||
use rocket::Route;
|
use rocket::Route;
|
||||||
|
|
||||||
mod hello;
|
|
||||||
mod complete;
|
mod complete;
|
||||||
|
mod hello;
|
||||||
|
|
||||||
pub fn routes() -> Vec<Route> {
|
pub fn routes() -> Vec<Route> {
|
||||||
routes! [
|
routes![hello::req, complete::req]
|
||||||
hello::req,
|
|
||||||
complete::req
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use crate::util::variables::{DISABLE_REGISTRATION, HCAPTCHA_SITEKEY, USE_EMAIL, USE_HCAPTCHA};
|
use crate::util::variables::{DISABLE_REGISTRATION, HCAPTCHA_SITEKEY, USE_EMAIL, USE_HCAPTCHA};
|
||||||
|
|
||||||
use rocket_contrib::json::JsonValue;
|
|
||||||
use mongodb::bson::doc;
|
use mongodb::bson::doc;
|
||||||
|
use rocket_contrib::json::JsonValue;
|
||||||
|
|
||||||
#[get("/")]
|
#[get("/")]
|
||||||
pub async fn root() -> JsonValue {
|
pub async fn root() -> JsonValue {
|
||||||
|
|||||||
@@ -1,8 +1,16 @@
|
|||||||
use crate::{database::{entities::{User, RelationshipStatus}, get_collection, guards::reference::Ref, permissions::get_relationship}, util::result::Error};
|
|
||||||
use rocket_contrib::json::JsonValue;
|
|
||||||
use crate::util::result::Result;
|
use crate::util::result::Result;
|
||||||
use mongodb::bson::doc;
|
use crate::{
|
||||||
|
database::{
|
||||||
|
entities::{RelationshipStatus, User},
|
||||||
|
get_collection,
|
||||||
|
guards::reference::Ref,
|
||||||
|
permissions::get_relationship,
|
||||||
|
},
|
||||||
|
util::result::Error,
|
||||||
|
};
|
||||||
use futures::try_join;
|
use futures::try_join;
|
||||||
|
use mongodb::bson::doc;
|
||||||
|
use rocket_contrib::json::JsonValue;
|
||||||
|
|
||||||
#[put("/<target>/friend")]
|
#[put("/<target>/friend")]
|
||||||
pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
|
pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
|
||||||
@@ -42,7 +50,10 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
|
|||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
Ok(_) => Ok(json!({ "status": "Friend" })),
|
Ok(_) => Ok(json!({ "status": "Friend" })),
|
||||||
Err(_) => Err(Error::DatabaseError { operation: "update_one", with: "user" })
|
Err(_) => Err(Error::DatabaseError {
|
||||||
|
operation: "update_one",
|
||||||
|
with: "user",
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RelationshipStatus::None => {
|
RelationshipStatus::None => {
|
||||||
@@ -77,7 +88,10 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
|
|||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
Ok(_) => Ok(json!({ "status": "Outgoing" })),
|
Ok(_) => Ok(json!({ "status": "Outgoing" })),
|
||||||
Err(_) => Err(Error::DatabaseError { operation: "update_one", with: "user" })
|
Err(_) => Err(Error::DatabaseError {
|
||||||
|
operation: "update_one",
|
||||||
|
with: "user",
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,18 @@
|
|||||||
use crate::{database::entities::RelationshipStatus, database::guards::reference::Ref, database::entities::User, database::permissions::get_relationship, util::result::Error, database::get_collection};
|
|
||||||
use rocket_contrib::json::JsonValue;
|
|
||||||
use crate::util::result::Result;
|
use crate::util::result::Result;
|
||||||
use mongodb::bson::doc;
|
use crate::{
|
||||||
|
database::entities::RelationshipStatus, database::entities::User, database::get_collection,
|
||||||
|
database::guards::reference::Ref, database::permissions::get_relationship, util::result::Error,
|
||||||
|
};
|
||||||
use futures::try_join;
|
use futures::try_join;
|
||||||
|
use mongodb::bson::doc;
|
||||||
|
use rocket_contrib::json::JsonValue;
|
||||||
|
|
||||||
#[put("/<target>/block")]
|
#[put("/<target>/block")]
|
||||||
pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
|
pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
|
||||||
let col = get_collection("users");
|
let col = get_collection("users");
|
||||||
|
|
||||||
match get_relationship(&user, &target) {
|
match get_relationship(&user, &target) {
|
||||||
RelationshipStatus::User |
|
RelationshipStatus::User | RelationshipStatus::Blocked => Err(Error::NoEffect),
|
||||||
RelationshipStatus::Blocked => Err(Error::NoEffect),
|
|
||||||
RelationshipStatus::BlockedOther => {
|
RelationshipStatus::BlockedOther => {
|
||||||
col.update_one(
|
col.update_one(
|
||||||
doc! {
|
doc! {
|
||||||
@@ -22,13 +24,16 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
|
|||||||
"relations.$.status": "Blocked"
|
"relations.$.status": "Blocked"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None
|
None,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.map_err(|_| Error::DatabaseError { operation: "update_one", with: "user" })?;
|
.map_err(|_| Error::DatabaseError {
|
||||||
|
operation: "update_one",
|
||||||
|
with: "user",
|
||||||
|
})?;
|
||||||
|
|
||||||
Ok(json!({ "status": "Blocked" }))
|
Ok(json!({ "status": "Blocked" }))
|
||||||
},
|
}
|
||||||
RelationshipStatus::None => {
|
RelationshipStatus::None => {
|
||||||
match try_join!(
|
match try_join!(
|
||||||
col.update_one(
|
col.update_one(
|
||||||
@@ -61,12 +66,15 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
|
|||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
Ok(_) => Ok(json!({ "status": "Blocked" })),
|
Ok(_) => Ok(json!({ "status": "Blocked" })),
|
||||||
Err(_) => Err(Error::DatabaseError { operation: "update_one", with: "user" })
|
Err(_) => Err(Error::DatabaseError {
|
||||||
|
operation: "update_one",
|
||||||
|
with: "user",
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
RelationshipStatus::Friend |
|
RelationshipStatus::Friend
|
||||||
RelationshipStatus::Incoming |
|
| RelationshipStatus::Incoming
|
||||||
RelationshipStatus::Outgoing => {
|
| RelationshipStatus::Outgoing => {
|
||||||
match try_join!(
|
match try_join!(
|
||||||
col.update_one(
|
col.update_one(
|
||||||
doc! {
|
doc! {
|
||||||
@@ -94,7 +102,10 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
|
|||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
Ok(_) => Ok(json!({ "status": "Blocked" })),
|
Ok(_) => Ok(json!({ "status": "Blocked" })),
|
||||||
Err(_) => Err(Error::DatabaseError { operation: "update_one", with: "user" })
|
Err(_) => Err(Error::DatabaseError {
|
||||||
|
operation: "update_one",
|
||||||
|
with: "user",
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
use crate::database::entities::{Channel, User};
|
use crate::database::entities::{Channel, User};
|
||||||
use mongodb::bson::{Bson, doc, from_bson};
|
|
||||||
use crate::util::result::{Error, Result};
|
|
||||||
use crate::database::get_collection;
|
use crate::database::get_collection;
|
||||||
use rocket_contrib::json::JsonValue;
|
use crate::util::result::{Error, Result};
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
|
use mongodb::bson::{doc, from_bson, Bson};
|
||||||
|
use rocket_contrib::json::JsonValue;
|
||||||
|
|
||||||
#[get("/dms")]
|
#[get("/dms")]
|
||||||
pub async fn req(user: User) -> Result<JsonValue> {
|
pub async fn req(user: User) -> Result<JsonValue> {
|
||||||
@@ -21,10 +21,13 @@ pub async fn req(user: User) -> Result<JsonValue> {
|
|||||||
],
|
],
|
||||||
"recipients": user.id
|
"recipients": user.id
|
||||||
},
|
},
|
||||||
None
|
None,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.map_err(|_| Error::DatabaseError { operation: "find", with: "channels" })?;
|
.map_err(|_| Error::DatabaseError {
|
||||||
|
operation: "find",
|
||||||
|
with: "channels",
|
||||||
|
})?;
|
||||||
|
|
||||||
let mut channels = vec![];
|
let mut channels = vec![];
|
||||||
while let Some(result) = cursor.next().await {
|
while let Some(result) = cursor.next().await {
|
||||||
@@ -33,7 +36,5 @@ pub async fn req(user: User) -> Result<JsonValue> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(json!(
|
Ok(json!(channels))
|
||||||
channels
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
use crate::database::{entities::User, guards::reference::Ref, permissions::get_relationship};
|
use crate::database::{entities::User, guards::reference::Ref, permissions::get_relationship};
|
||||||
use rocket_contrib::json::JsonValue;
|
|
||||||
use crate::util::result::Result;
|
use crate::util::result::Result;
|
||||||
|
use rocket_contrib::json::JsonValue;
|
||||||
|
|
||||||
#[get("/<target>/relationship")]
|
#[get("/<target>/relationship")]
|
||||||
pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
|
pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
|
||||||
Ok(json!({
|
Ok(json!({ "status": get_relationship(&user, &target) }))
|
||||||
"status": get_relationship(&user, &target)
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
use crate::database::entities::User;
|
use crate::database::entities::User;
|
||||||
use rocket_contrib::json::JsonValue;
|
|
||||||
use crate::util::result::Result;
|
use crate::util::result::Result;
|
||||||
|
use rocket_contrib::json::JsonValue;
|
||||||
|
|
||||||
#[get("/relationships")]
|
#[get("/relationships")]
|
||||||
pub async fn req(user: User) -> Result<JsonValue> {
|
pub async fn req(user: User) -> Result<JsonValue> {
|
||||||
Ok(
|
Ok(if let Some(vec) = user.relations {
|
||||||
if let Some(vec) = user.relations {
|
json!(vec)
|
||||||
json!(vec)
|
} else {
|
||||||
} else {
|
json!([])
|
||||||
json!([])
|
})
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
use crate::database::entities::User;
|
||||||
use crate::database::guards::reference::Ref;
|
use crate::database::guards::reference::Ref;
|
||||||
use crate::util::result::{Error, Result};
|
use crate::util::result::{Error, Result};
|
||||||
use crate::database::entities::User;
|
|
||||||
use rocket_contrib::json::JsonValue;
|
use rocket_contrib::json::JsonValue;
|
||||||
|
|
||||||
#[get("/<target>")]
|
#[get("/<target>")]
|
||||||
|
|||||||
@@ -1,24 +1,22 @@
|
|||||||
use rocket::Route;
|
use rocket::Route;
|
||||||
|
|
||||||
mod fetch_user;
|
|
||||||
mod fetch_dms;
|
|
||||||
mod open_dm;
|
|
||||||
mod fetch_relationships;
|
|
||||||
mod fetch_relationship;
|
|
||||||
mod add_friend;
|
mod add_friend;
|
||||||
mod remove_friend;
|
|
||||||
mod block_user;
|
mod block_user;
|
||||||
|
mod fetch_dms;
|
||||||
|
mod fetch_relationship;
|
||||||
|
mod fetch_relationships;
|
||||||
|
mod fetch_user;
|
||||||
|
mod open_dm;
|
||||||
|
mod remove_friend;
|
||||||
mod unblock_user;
|
mod unblock_user;
|
||||||
|
|
||||||
pub fn routes() -> Vec<Route> {
|
pub fn routes() -> Vec<Route> {
|
||||||
routes! [
|
routes![
|
||||||
// User Information
|
// User Information
|
||||||
fetch_user::req,
|
fetch_user::req,
|
||||||
|
|
||||||
// Direct Messaging
|
// Direct Messaging
|
||||||
fetch_dms::req,
|
fetch_dms::req,
|
||||||
open_dm::req,
|
open_dm::req,
|
||||||
|
|
||||||
// Relationships
|
// Relationships
|
||||||
fetch_relationships::req,
|
fetch_relationships::req,
|
||||||
fetch_relationship::req,
|
fetch_relationship::req,
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
use crate::database::entities::{Channel, User};
|
use crate::database::entities::{Channel, User};
|
||||||
|
use crate::database::get_collection;
|
||||||
use crate::database::guards::reference::Ref;
|
use crate::database::guards::reference::Ref;
|
||||||
use crate::util::result::{Error, Result};
|
use crate::util::result::{Error, Result};
|
||||||
use crate::database::get_collection;
|
|
||||||
use rocket_contrib::json::JsonValue;
|
|
||||||
use mongodb::bson::doc;
|
use mongodb::bson::doc;
|
||||||
|
use rocket_contrib::json::JsonValue;
|
||||||
use ulid::Ulid;
|
use ulid::Ulid;
|
||||||
|
|
||||||
#[get("/<target>/dm")]
|
#[get("/<target>/dm")]
|
||||||
@@ -25,25 +25,22 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
|
|||||||
let existing_channel = get_collection("channels")
|
let existing_channel = get_collection("channels")
|
||||||
.find_one(query, None)
|
.find_one(query, None)
|
||||||
.await
|
.await
|
||||||
.map_err(|_| Error::DatabaseError { operation: "find_one", with: "channel" })?;
|
.map_err(|_| Error::DatabaseError {
|
||||||
|
operation: "find_one",
|
||||||
|
with: "channel",
|
||||||
|
})?;
|
||||||
|
|
||||||
if let Some(doc) = existing_channel {
|
if let Some(doc) = existing_channel {
|
||||||
Ok(json!(doc))
|
Ok(json!(doc))
|
||||||
} else {
|
} else {
|
||||||
let id = Ulid::new().to_string();
|
let id = Ulid::new().to_string();
|
||||||
let channel = if user.id == target.id {
|
let channel = if user.id == target.id {
|
||||||
Channel::SavedMessages {
|
Channel::SavedMessages { id, user: user.id }
|
||||||
id,
|
|
||||||
user: user.id
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
Channel::DirectMessage {
|
Channel::DirectMessage {
|
||||||
id,
|
id,
|
||||||
active: false,
|
active: false,
|
||||||
recipients: vec! [
|
recipients: vec![user.id, target.id],
|
||||||
user.id,
|
|
||||||
target.id
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +1,24 @@
|
|||||||
use crate::{database::entities::RelationshipStatus, database::guards::reference::Ref, database::entities::User, database::permissions::get_relationship, util::result::Error, database::get_collection};
|
|
||||||
use rocket_contrib::json::JsonValue;
|
|
||||||
use crate::util::result::Result;
|
use crate::util::result::Result;
|
||||||
use mongodb::bson::doc;
|
use crate::{
|
||||||
|
database::entities::RelationshipStatus, database::entities::User, database::get_collection,
|
||||||
|
database::guards::reference::Ref, database::permissions::get_relationship, util::result::Error,
|
||||||
|
};
|
||||||
use futures::try_join;
|
use futures::try_join;
|
||||||
|
use mongodb::bson::doc;
|
||||||
|
use rocket_contrib::json::JsonValue;
|
||||||
|
|
||||||
#[delete("/<target>/friend")]
|
#[delete("/<target>/friend")]
|
||||||
pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
|
pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
|
||||||
let col = get_collection("users");
|
let col = get_collection("users");
|
||||||
|
|
||||||
match get_relationship(&user, &target) {
|
match get_relationship(&user, &target) {
|
||||||
RelationshipStatus::Blocked |
|
RelationshipStatus::Blocked
|
||||||
RelationshipStatus::BlockedOther |
|
| RelationshipStatus::BlockedOther
|
||||||
RelationshipStatus::User |
|
| RelationshipStatus::User
|
||||||
RelationshipStatus::None => Err(Error::NoEffect),
|
| RelationshipStatus::None => Err(Error::NoEffect),
|
||||||
RelationshipStatus::Friend |
|
RelationshipStatus::Friend
|
||||||
RelationshipStatus::Outgoing |
|
| RelationshipStatus::Outgoing
|
||||||
RelationshipStatus::Incoming => {
|
| RelationshipStatus::Incoming => {
|
||||||
match try_join!(
|
match try_join!(
|
||||||
col.update_one(
|
col.update_one(
|
||||||
doc! {
|
doc! {
|
||||||
@@ -45,7 +48,10 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
|
|||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
Ok(_) => Ok(json!({ "status": "None" })),
|
Ok(_) => Ok(json!({ "status": "None" })),
|
||||||
Err(_) => Err(Error::DatabaseError { operation: "update_one", with: "user" })
|
Err(_) => Err(Error::DatabaseError {
|
||||||
|
operation: "update_one",
|
||||||
|
with: "user",
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,23 @@
|
|||||||
use crate::{database::entities::RelationshipStatus, database::guards::reference::Ref, database::entities::User, database::permissions::get_relationship, util::result::Error, database::get_collection};
|
|
||||||
use rocket_contrib::json::JsonValue;
|
|
||||||
use crate::util::result::Result;
|
use crate::util::result::Result;
|
||||||
use mongodb::bson::doc;
|
use crate::{
|
||||||
|
database::entities::RelationshipStatus, database::entities::User, database::get_collection,
|
||||||
|
database::guards::reference::Ref, database::permissions::get_relationship, util::result::Error,
|
||||||
|
};
|
||||||
use futures::try_join;
|
use futures::try_join;
|
||||||
|
use mongodb::bson::doc;
|
||||||
|
use rocket_contrib::json::JsonValue;
|
||||||
|
|
||||||
#[delete("/<target>/block")]
|
#[delete("/<target>/block")]
|
||||||
pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
|
pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
|
||||||
let col = get_collection("users");
|
let col = get_collection("users");
|
||||||
|
|
||||||
match get_relationship(&user, &target) {
|
match get_relationship(&user, &target) {
|
||||||
RelationshipStatus::None |
|
RelationshipStatus::None
|
||||||
RelationshipStatus::User |
|
| RelationshipStatus::User
|
||||||
RelationshipStatus::BlockedOther |
|
| RelationshipStatus::BlockedOther
|
||||||
RelationshipStatus::Incoming |
|
| RelationshipStatus::Incoming
|
||||||
RelationshipStatus::Outgoing |
|
| RelationshipStatus::Outgoing
|
||||||
RelationshipStatus::Friend => Err(Error::NoEffect),
|
| RelationshipStatus::Friend => Err(Error::NoEffect),
|
||||||
RelationshipStatus::Blocked => {
|
RelationshipStatus::Blocked => {
|
||||||
match get_relationship(&target.fetch_user().await?, &user.as_ref()) {
|
match get_relationship(&target.fetch_user().await?, &user.as_ref()) {
|
||||||
RelationshipStatus::Blocked => {
|
RelationshipStatus::Blocked => {
|
||||||
@@ -28,13 +31,16 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
|
|||||||
"relations.$.status": "BlockedOther"
|
"relations.$.status": "BlockedOther"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None
|
None,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.map_err(|_| Error::DatabaseError { operation: "update_one", with: "user" })?;
|
.map_err(|_| Error::DatabaseError {
|
||||||
|
operation: "update_one",
|
||||||
|
with: "user",
|
||||||
|
})?;
|
||||||
|
|
||||||
Ok(json!({ "status": "BlockedOther" }))
|
Ok(json!({ "status": "BlockedOther" }))
|
||||||
},
|
}
|
||||||
RelationshipStatus::BlockedOther => {
|
RelationshipStatus::BlockedOther => {
|
||||||
match try_join!(
|
match try_join!(
|
||||||
col.update_one(
|
col.update_one(
|
||||||
@@ -65,10 +71,13 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
|
|||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
Ok(_) => Ok(json!({ "status": "None" })),
|
Ok(_) => Ok(json!({ "status": "None" })),
|
||||||
Err(_) => Err(Error::DatabaseError { operation: "update_one", with: "user" })
|
Err(_) => Err(Error::DatabaseError {
|
||||||
|
operation: "update_one",
|
||||||
|
with: "user",
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
_ => Err(Error::InternalError)
|
_ => Err(Error::InternalError),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ use rand::{distributions::Alphanumeric, Rng};
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::iter::FromIterator;
|
use std::iter::FromIterator;
|
||||||
|
|
||||||
|
pub mod captcha;
|
||||||
pub mod email;
|
pub mod email;
|
||||||
pub mod result;
|
pub mod result;
|
||||||
pub mod captcha;
|
|
||||||
pub mod variables;
|
pub mod variables;
|
||||||
|
|
||||||
pub fn vec_to_set<T: Clone + Eq + std::hash::Hash>(data: &[T]) -> HashSet<T> {
|
pub fn vec_to_set<T: Clone + Eq + std::hash::Hash>(data: &[T]) -> HashSet<T> {
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
use rocket::response::{self, Responder, Response};
|
|
||||||
use rocket::http::{ContentType, Status};
|
|
||||||
use validator::ValidationErrors;
|
|
||||||
use rocket::request::Request;
|
|
||||||
use serde::Serialize;
|
|
||||||
use std::io::Cursor;
|
|
||||||
use snafu::Snafu;
|
|
||||||
use json;
|
use json;
|
||||||
|
use rocket::http::{ContentType, Status};
|
||||||
|
use rocket::request::Request;
|
||||||
|
use rocket::response::{self, Responder, Response};
|
||||||
|
use serde::Serialize;
|
||||||
|
use snafu::Snafu;
|
||||||
|
use std::io::Cursor;
|
||||||
|
use validator::ValidationErrors;
|
||||||
|
|
||||||
#[derive(Serialize, Debug, Snafu)]
|
#[derive(Serialize, Debug, Snafu)]
|
||||||
#[serde(tag = "type")]
|
#[serde(tag = "type")]
|
||||||
@@ -35,7 +35,10 @@ pub enum Error {
|
|||||||
#[snafu(display("Failed to validate fields."))]
|
#[snafu(display("Failed to validate fields."))]
|
||||||
FailedValidation { error: ValidationErrors },
|
FailedValidation { error: ValidationErrors },
|
||||||
#[snafu(display("Encountered a database error."))]
|
#[snafu(display("Encountered a database error."))]
|
||||||
DatabaseError { operation: &'static str, with: &'static str },
|
DatabaseError {
|
||||||
|
operation: &'static str,
|
||||||
|
with: &'static str,
|
||||||
|
},
|
||||||
#[snafu(display("Internal server error."))]
|
#[snafu(display("Internal server error."))]
|
||||||
InternalError,
|
InternalError,
|
||||||
#[snafu(display("This request had no effect."))]
|
#[snafu(display("This request had no effect."))]
|
||||||
|
|||||||
Reference in New Issue
Block a user