Ready payload on websocket, add friend by username + avatars.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -3,3 +3,4 @@ Rocket.toml
|
|||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
.mongo
|
.mongo
|
||||||
.env
|
.env
|
||||||
|
avatar.png
|
||||||
|
|||||||
5
Cargo.lock
generated
5
Cargo.lock
generated
@@ -983,8 +983,9 @@ checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hive_pubsub"
|
name = "hive_pubsub"
|
||||||
version = "0.4.2"
|
version = "0.4.3"
|
||||||
source = "git+https://gitlab.insrt.uk/insert/hive#7ab66da23bc86b6fa6497aac928d29d4b885a878"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "83760410241f6db418bb15e54b506a0887e7240286e29e5b0d2d88f5d1659b24"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures",
|
"futures",
|
||||||
"many-to-many",
|
"many-to-many",
|
||||||
|
|||||||
@@ -15,10 +15,11 @@ async-tungstenite = { version = "0.10.0", features = ["async-std-runtime"] }
|
|||||||
rauth = { git = "https://gitlab.insrt.uk/insert/rauth" }
|
rauth = { git = "https://gitlab.insrt.uk/insert/rauth" }
|
||||||
async-std = { version = "1.8.0", features = ["tokio02"] }
|
async-std = { version = "1.8.0", features = ["tokio02"] }
|
||||||
|
|
||||||
hive_pubsub = { git = "https://gitlab.insrt.uk/insert/hive", features = ["mongo"] }
|
hive_pubsub = { version = "0.4.3", features = ["mongo"] }
|
||||||
rocket_cors = { git = "https://github.com/lawliet89/rocket_cors", branch = "master" }
|
rocket_cors = { git = "https://github.com/lawliet89/rocket_cors", branch = "master" }
|
||||||
rocket_contrib = { git = "https://github.com/SergioBenitez/Rocket", branch = "master" }
|
rocket_contrib = { git = "https://github.com/SergioBenitez/Rocket", branch = "master" }
|
||||||
rocket = { git = "https://github.com/SergioBenitez/Rocket", branch = "master", default-features = false }
|
rocket = { git = "https://github.com/SergioBenitez/Rocket", branch = "master", default-features = false }
|
||||||
|
# ! FIXME: Switch to async-std runtime.
|
||||||
mongodb = { version = "1.1.1", features = ["tokio-runtime"], default-features = false }
|
mongodb = { version = "1.1.1", features = ["tokio-runtime"], default-features = false }
|
||||||
|
|
||||||
once_cell = "1.4.1"
|
once_cell = "1.4.1"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# Build Stage
|
# Build Stage
|
||||||
FROM ekidd/rust-musl-builder:nightly-2020-08-26 AS builder
|
FROM ekidd/rust-musl-builder:nightly-2020-11-19 AS builder
|
||||||
WORKDIR /home/rust/src
|
WORKDIR /home/rust/src
|
||||||
|
|
||||||
RUN USER=root cargo new --bin revolt
|
RUN USER=root cargo new --bin revolt
|
||||||
|
|||||||
@@ -1,22 +1,2 @@
|
|||||||
pub mod reference;
|
pub mod reference;
|
||||||
pub mod user;
|
pub mod user;
|
||||||
|
|
||||||
/*
|
|
||||||
// ! FIXME
|
|
||||||
impl<'r> FromParam<'r> for User {
|
|
||||||
type Error = &'r RawStr;
|
|
||||||
|
|
||||||
fn from_param(param: &'r RawStr) -> Result<Self, Self::Error> {
|
|
||||||
Err(param)
|
|
||||||
/*if let Ok(result) = fetch_channel(param).await {
|
|
||||||
if let Some(channel) = result {
|
|
||||||
Ok(channel)
|
|
||||||
} else {
|
|
||||||
Err(param)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Err(param)
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ use rauth::auth::Session;
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use snafu::Snafu;
|
use snafu::Snafu;
|
||||||
|
|
||||||
use crate::database::entities::RelationshipStatus;
|
use crate::database::entities::{RelationshipStatus, User};
|
||||||
|
|
||||||
use super::hive::get_hive;
|
use super::hive::get_hive;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Snafu)]
|
#[derive(Serialize, Deserialize, Debug, Snafu)]
|
||||||
#[serde(tag = "type")]
|
#[serde(tag = "error")]
|
||||||
pub enum WebSocketError {
|
pub enum WebSocketError {
|
||||||
#[snafu(display("This error has not been labelled."))]
|
#[snafu(display("This error has not been labelled."))]
|
||||||
LabelMe,
|
LabelMe,
|
||||||
@@ -32,6 +32,9 @@ pub enum ServerboundNotification {
|
|||||||
pub enum ClientboundNotification {
|
pub enum ClientboundNotification {
|
||||||
Error(WebSocketError),
|
Error(WebSocketError),
|
||||||
Authenticated,
|
Authenticated,
|
||||||
|
Ready {
|
||||||
|
user: User
|
||||||
|
},
|
||||||
|
|
||||||
/*MessageCreate {
|
/*MessageCreate {
|
||||||
id: String,
|
id: String,
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ async fn accept(stream: TcpStream) {
|
|||||||
subscriptions::generate_subscriptions(&user),
|
subscriptions::generate_subscriptions(&user),
|
||||||
) {
|
) {
|
||||||
send(ClientboundNotification::Authenticated);
|
send(ClientboundNotification::Authenticated);
|
||||||
|
send(ClientboundNotification::Ready { user });
|
||||||
} else {
|
} else {
|
||||||
send(ClientboundNotification::Error(
|
send(ClientboundNotification::Error(
|
||||||
WebSocketError::InternalError,
|
WebSocketError::InternalError,
|
||||||
|
|||||||
@@ -13,13 +13,29 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use futures::try_join;
|
use futures::try_join;
|
||||||
use mongodb::bson::doc;
|
use mongodb::bson::doc;
|
||||||
|
use mongodb::options::{FindOneOptions, Collation};
|
||||||
use rocket_contrib::json::JsonValue;
|
use rocket_contrib::json::JsonValue;
|
||||||
|
|
||||||
#[put("/<target>/friend")]
|
#[put("/<username>/friend")]
|
||||||
pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
|
pub async fn req(user: User, username: String) -> Result<JsonValue> {
|
||||||
let col = get_collection("users");
|
let col = get_collection("users");
|
||||||
|
let doc = col.find_one(
|
||||||
|
doc! {
|
||||||
|
"username": username
|
||||||
|
},
|
||||||
|
FindOneOptions::builder()
|
||||||
|
.collation(Collation::builder().locale("en").strength(2).build())
|
||||||
|
.build(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map_err(|_| Error::DatabaseError { operation: "find_one", with: "user" })?
|
||||||
|
.ok_or_else(|| Error::UnknownUser)?;
|
||||||
|
|
||||||
match get_relationship(&user, &target) {
|
let target_id = doc
|
||||||
|
.get_str("_id")
|
||||||
|
.map_err(|_| Error::DatabaseError { operation: "get_str(_id)", with: "user" })?;
|
||||||
|
|
||||||
|
match get_relationship(&user, &Ref { id: target_id.to_string() }) {
|
||||||
RelationshipStatus::User => return Err(Error::NoEffect),
|
RelationshipStatus::User => return Err(Error::NoEffect),
|
||||||
RelationshipStatus::Friend => return Err(Error::AlreadyFriends),
|
RelationshipStatus::Friend => return Err(Error::AlreadyFriends),
|
||||||
RelationshipStatus::Outgoing => return Err(Error::AlreadySentRequest),
|
RelationshipStatus::Outgoing => return Err(Error::AlreadySentRequest),
|
||||||
@@ -30,7 +46,7 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
|
|||||||
col.update_one(
|
col.update_one(
|
||||||
doc! {
|
doc! {
|
||||||
"_id": &user.id,
|
"_id": &user.id,
|
||||||
"relations._id": &target.id
|
"relations._id": target_id
|
||||||
},
|
},
|
||||||
doc! {
|
doc! {
|
||||||
"$set": {
|
"$set": {
|
||||||
@@ -41,7 +57,7 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
|
|||||||
),
|
),
|
||||||
col.update_one(
|
col.update_one(
|
||||||
doc! {
|
doc! {
|
||||||
"_id": &target.id,
|
"_id": target_id,
|
||||||
"relations._id": &user.id
|
"relations._id": &user.id
|
||||||
},
|
},
|
||||||
doc! {
|
doc! {
|
||||||
@@ -56,16 +72,16 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
|
|||||||
try_join!(
|
try_join!(
|
||||||
ClientboundNotification::UserRelationship {
|
ClientboundNotification::UserRelationship {
|
||||||
id: user.id.clone(),
|
id: user.id.clone(),
|
||||||
user: target.id.clone(),
|
user: target_id.to_string(),
|
||||||
status: RelationshipStatus::Friend
|
status: RelationshipStatus::Friend
|
||||||
}
|
}
|
||||||
.publish(user.id.clone()),
|
.publish(user.id.clone()),
|
||||||
ClientboundNotification::UserRelationship {
|
ClientboundNotification::UserRelationship {
|
||||||
id: target.id.clone(),
|
id: target_id.to_string(),
|
||||||
user: user.id.clone(),
|
user: user.id.clone(),
|
||||||
status: RelationshipStatus::Friend
|
status: RelationshipStatus::Friend
|
||||||
}
|
}
|
||||||
.publish(target.id.clone())
|
.publish(target_id.to_string())
|
||||||
)
|
)
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
@@ -86,7 +102,7 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
|
|||||||
doc! {
|
doc! {
|
||||||
"$push": {
|
"$push": {
|
||||||
"relations": {
|
"relations": {
|
||||||
"_id": &target.id,
|
"_id": target_id,
|
||||||
"status": "Outgoing"
|
"status": "Outgoing"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -95,7 +111,7 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
|
|||||||
),
|
),
|
||||||
col.update_one(
|
col.update_one(
|
||||||
doc! {
|
doc! {
|
||||||
"_id": &target.id
|
"_id": target_id
|
||||||
},
|
},
|
||||||
doc! {
|
doc! {
|
||||||
"$push": {
|
"$push": {
|
||||||
@@ -112,21 +128,21 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
|
|||||||
try_join!(
|
try_join!(
|
||||||
ClientboundNotification::UserRelationship {
|
ClientboundNotification::UserRelationship {
|
||||||
id: user.id.clone(),
|
id: user.id.clone(),
|
||||||
user: target.id.clone(),
|
user: target_id.to_string(),
|
||||||
status: RelationshipStatus::Outgoing
|
status: RelationshipStatus::Outgoing
|
||||||
}
|
}
|
||||||
.publish(user.id.clone()),
|
.publish(user.id.clone()),
|
||||||
ClientboundNotification::UserRelationship {
|
ClientboundNotification::UserRelationship {
|
||||||
id: target.id.clone(),
|
id: target_id.to_string(),
|
||||||
user: user.id.clone(),
|
user: user.id.clone(),
|
||||||
status: RelationshipStatus::Incoming
|
status: RelationshipStatus::Incoming
|
||||||
}
|
}
|
||||||
.publish(target.id.clone())
|
.publish(target_id.to_string())
|
||||||
)
|
)
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
hive::subscribe_if_exists(user.id.clone(), target.id.clone()).ok();
|
hive::subscribe_if_exists(user.id.clone(), target_id.to_string()).ok();
|
||||||
hive::subscribe_if_exists(target.id.clone(), user.id.clone()).ok();
|
hive::subscribe_if_exists(target_id.to_string(), user.id.clone()).ok();
|
||||||
|
|
||||||
Ok(json!({ "status": "Outgoing" }))
|
Ok(json!({ "status": "Outgoing" }))
|
||||||
}
|
}
|
||||||
|
|||||||
7
src/routes/users/get_avatar.rs
Normal file
7
src/routes/users/get_avatar.rs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
use rocket::response::NamedFile;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
#[get("/<_target>/avatar")]
|
||||||
|
pub async fn req(_target: String) -> Option<NamedFile> {
|
||||||
|
NamedFile::open(Path::new("avatar.png")).await.ok()
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
use rocket::Route;
|
use rocket::Route;
|
||||||
|
|
||||||
mod add_friend;
|
mod add_friend;
|
||||||
|
mod get_avatar;
|
||||||
mod block_user;
|
mod block_user;
|
||||||
mod fetch_dms;
|
mod fetch_dms;
|
||||||
mod fetch_relationship;
|
mod fetch_relationship;
|
||||||
@@ -14,9 +15,12 @@ pub fn routes() -> Vec<Route> {
|
|||||||
routes![
|
routes![
|
||||||
// User Information
|
// User Information
|
||||||
fetch_user::req,
|
fetch_user::req,
|
||||||
|
get_avatar::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,
|
||||||
|
|||||||
Reference in New Issue
Block a user