Skip to content
Snippets Groups Projects
Verified Commit 331d636f authored by insert's avatar insert
Browse files

Re-do guards, streamline requests.

parent e2e5a081
No related merge requests found
use serde::{ Deserialize, Serialize };
#[derive(Serialize, Deserialize, Debug)]
pub struct Channel {
#[serde(rename = "_id")]
pub id: String,
pub channel_type: u8,
// for Direct Messages
pub recipients: Option<Vec<String>>,
pub active: Option<bool>,
}
use serde::{ Deserialize, Serialize };
#[derive(Serialize, Deserialize, Debug)]
pub struct Message {
#[serde(rename = "_id")]
pub id: String,
}
...@@ -24,4 +24,6 @@ pub fn get_collection(collection: &str) -> Collection { ...@@ -24,4 +24,6 @@ pub fn get_collection(collection: &str) -> Collection {
get_db().collection(collection) get_db().collection(collection)
} }
pub mod user; pub mod user;
\ No newline at end of file pub mod channel;
pub mod message;
...@@ -3,15 +3,9 @@ use rocket::http::{ Status, RawStr }; ...@@ -3,15 +3,9 @@ use rocket::http::{ Status, RawStr };
use rocket::request::{ self, Request, FromRequest, FromParam }; use rocket::request::{ self, Request, FromRequest, FromParam };
use bson::{ bson, doc, from_bson }; use bson::{ bson, doc, from_bson };
use ulid::Ulid;
use crate::database; use crate::database;
use database::user::User;
pub struct User(
pub Ulid,
pub String,
pub database::user::User,
);
#[derive(Debug)] #[derive(Debug)]
pub enum AuthError { pub enum AuthError {
...@@ -33,11 +27,7 @@ impl<'a, 'r> FromRequest<'a, 'r> for User { ...@@ -33,11 +27,7 @@ impl<'a, 'r> FromRequest<'a, 'r> for User {
let result = col.find_one(doc! { "access_token": key }, None).unwrap(); let result = col.find_one(doc! { "access_token": key }, None).unwrap();
if let Some(user) = result { if let Some(user) = result {
Outcome::Success(User ( Outcome::Success(from_bson(bson::Bson::Document(user)).expect("Failed to unwrap user."))
Ulid::from_string(user.get_str("_id").unwrap()).unwrap(),
user.get_str("username").unwrap().to_string(),
from_bson(bson::Bson::Document(user)).expect("Failed to unwrap user.")
))
} else { } else {
Outcome::Failure((Status::Forbidden, AuthError::Invalid)) Outcome::Failure((Status::Forbidden, AuthError::Invalid))
} }
...@@ -55,11 +45,7 @@ impl<'r> FromParam<'r> for User { ...@@ -55,11 +45,7 @@ impl<'r> FromParam<'r> for User {
let result = col.find_one(doc! { "_id": param.to_string() }, None).unwrap(); let result = col.find_one(doc! { "_id": param.to_string() }, None).unwrap();
if let Some(user) = result { if let Some(user) = result {
Ok(User ( Ok(from_bson(bson::Bson::Document(user)).expect("Failed to unwrap user."))
Ulid::from_string(user.get_str("_id").unwrap()).unwrap(),
user.get_str("username").unwrap().to_string(),
from_bson(bson::Bson::Document(user)).expect("Failed to unwrap user.")
))
} else { } else {
Err(param) Err(param)
} }
......
use rocket::Outcome; use rocket::http::{ RawStr };
use rocket::http::{ Status, RawStr }; use rocket::request::{ FromParam };
use rocket::request::{ self, Request, FromRequest, FromParam }; use bson::{ bson, doc, from_bson };
use bson::{ bson, doc, ordered::OrderedDocument };
use std::convert::TryFrom;
use ulid::Ulid;
use crate::database; use crate::database;
use crate::routes::channel::ChannelType;
pub struct Channel (
pub Ulid,
pub ChannelType,
pub OrderedDocument,
);
pub struct Message ( use database::channel::Channel;
pub Ulid, use database::message::Message;
pub OrderedDocument,
);
impl<'r> FromParam<'r> for Channel { impl<'r> FromParam<'r> for Channel {
type Error = &'r RawStr; type Error = &'r RawStr;
...@@ -28,11 +15,7 @@ impl<'r> FromParam<'r> for Channel { ...@@ -28,11 +15,7 @@ impl<'r> FromParam<'r> for Channel {
let result = col.find_one(doc! { "_id": param.to_string() }, None).unwrap(); let result = col.find_one(doc! { "_id": param.to_string() }, None).unwrap();
if let Some(channel) = result { if let Some(channel) = result {
Ok(Channel ( Ok(from_bson(bson::Bson::Document(channel)).expect("Failed to unwrap channel."))
Ulid::from_string(channel.get_str("_id").unwrap()).unwrap(),
ChannelType::try_from(channel.get_i32("type").unwrap() as usize).unwrap(),
channel
))
} else { } else {
Err(param) Err(param)
} }
...@@ -47,10 +30,7 @@ impl<'r> FromParam<'r> for Message { ...@@ -47,10 +30,7 @@ impl<'r> FromParam<'r> for Message {
let result = col.find_one(doc! { "_id": param.to_string() }, None).unwrap(); let result = col.find_one(doc! { "_id": param.to_string() }, None).unwrap();
if let Some(message) = result { if let Some(message) = result {
Ok(Message ( Ok(from_bson(bson::Bson::Document(message)).expect("Failed to unwrap message."))
Ulid::from_string(message.get_str("_id").unwrap()).unwrap(),
message
))
} else { } else {
Err(param) Err(param)
} }
......
use crate::guards::{ auth::User, channel::Channel }; use crate::database::{ user::User, channel::Channel };
use crate::database;
use rocket_contrib::json::{ Json, JsonValue }; use rocket_contrib::json::{ JsonValue };
use serde::{ Serialize, Deserialize };
use mongodb::options::FindOptions;
use num_enum::TryFromPrimitive; use num_enum::TryFromPrimitive;
use bson::{ bson, doc }; use bson::{ doc };
use ulid::Ulid;
#[derive(Debug, TryFromPrimitive)] #[derive(Debug, TryFromPrimitive)]
#[repr(usize)] #[repr(usize)]
...@@ -17,19 +13,21 @@ pub enum ChannelType { ...@@ -17,19 +13,21 @@ pub enum ChannelType {
} }
fn has_permission(user: &User, target: &Channel) -> bool { fn has_permission(user: &User, target: &Channel) -> bool {
let id = user.0.to_string(); match target.channel_type {
match target.1 { 0..=1 => {
ChannelType::DM | if let Some(arr) = &target.recipients {
ChannelType::GROUP_DM => { for item in arr {
for user in target.2.get_array("recipients").expect("DB[recipients]") { if item == &user.id {
if user.as_str().expect("Expected string id.") == id { return true;
return true; }
} }
} }
false false
}, },
ChannelType::GUILD_CHANNEL => 2 =>
false,
_ =>
false false
} }
} }
...@@ -41,12 +39,10 @@ pub fn channel(user: User, target: Channel) -> Option<JsonValue> { ...@@ -41,12 +39,10 @@ pub fn channel(user: User, target: Channel) -> Option<JsonValue> {
return None return None
} }
let Channel ( id, channel_type, doc ) = target;
Some( Some(
json!({ json!({
"id": id.to_string(), "id": target.id,
"type": channel_type as u8 "type": target.channel_type
} }
)) ))
} }
use crate::guards::auth::User; use crate::database::{ self, user::User, channel::Channel };
use crate::database;
use crate::routes::channel; use crate::routes::channel;
use rocket_contrib::json::{ Json, JsonValue }; use rocket_contrib::json::{ Json, JsonValue };
...@@ -11,14 +10,12 @@ use ulid::Ulid; ...@@ -11,14 +10,12 @@ use ulid::Ulid;
/// retrieve your user information /// retrieve your user information
#[get("/@me")] #[get("/@me")]
pub fn me(user: User) -> JsonValue { pub fn me(user: User) -> JsonValue {
let User ( id, username, doc ) = user;
json!({ json!({
"id": id.to_string(), "id": user.id,
"username": username, "username": user.username,
"email": doc.email, "email": user.email,
"verified": doc.email_verification.verified, "verified": user.email_verification.verified,
"created_timestamp": id.datetime().timestamp(), "created_timestamp": Ulid::from_string(&user.id).unwrap().datetime().timestamp(),
}) })
} }
...@@ -46,7 +43,7 @@ pub fn lookup(_user: User, query: Json<Query>) -> JsonValue { ...@@ -46,7 +43,7 @@ pub fn lookup(_user: User, query: Json<Query>) -> JsonValue {
let mut results = Vec::new(); let mut results = Vec::new();
for user in users { for user in users {
let u: database::user::User = from_bson(bson::Bson::Document(user.unwrap())).expect("Failed to unwrap user."); let u: User = from_bson(bson::Bson::Document(user.unwrap())).expect("Failed to unwrap user.");
results.push( results.push(
json!({ json!({
"id": u.id, "id": u.id,
...@@ -73,35 +70,21 @@ pub fn dms(user: User) -> JsonValue { ...@@ -73,35 +70,21 @@ pub fn dms(user: User) -> JsonValue {
"type": channel::ChannelType::GROUP_DM as i32 "type": channel::ChannelType::GROUP_DM as i32
} }
], ],
"recipients": user.0.to_string() "recipients": user.id
}, },
None None
).expect("Failed channel lookup"); ).expect("Failed channel lookup");
let mut channels = Vec::new(); let mut channels = Vec::new();
for res in results { for item in results {
let doc = res.expect("Failed to unwrap document"); let channel: Channel = from_bson(bson::Bson::Document(item.unwrap())).expect("Failed to unwrap channel.");
let mut recipients = Vec::new();
for user in doc.get_array("recipients").expect("DB[recipients]") {
recipients.push(
user.as_str()
.expect("Should be a string.")
);
}
let active =
match doc.get_bool("active") {
Ok(x) => x,
Err(_) => true
};
channels.push( channels.push(
json!({ json!({
"id": doc.get_str("_id").expect("DB[id]"), "id": channel.id,
"type": doc.get_i32("type").expect("DB[type]"), "type": channel.channel_type,
"recipients": recipients, "recipients": channel.recipients,
"active": active "active": channel.active.unwrap()
}) })
); );
} }
...@@ -115,12 +98,12 @@ pub fn dm(user: User, target: User) -> JsonValue { ...@@ -115,12 +98,12 @@ pub fn dm(user: User, target: User) -> JsonValue {
let col = database::get_collection("channels"); let col = database::get_collection("channels");
match col.find_one( match col.find_one(
doc! { "type": channel::ChannelType::DM as i32, "recipients": [ user.0.to_string(), target.0.to_string() ] }, doc! { "type": channel::ChannelType::DM as i32, "recipients": [ user.id.clone(), target.id.clone() ] },
None None
).expect("Failed channel lookup") { ).expect("Failed channel lookup") {
Some(channel) => Some(channel) =>
json!({ json!({
"id": channel.get_str("_id").expect("DB[id]") "id": channel.get_str("_id").unwrap()
}), }),
None => { None => {
let id = Ulid::new(); let id = Ulid::new();
...@@ -129,7 +112,7 @@ pub fn dm(user: User, target: User) -> JsonValue { ...@@ -129,7 +112,7 @@ pub fn dm(user: User, target: User) -> JsonValue {
doc! { doc! {
"_id": id.to_string(), "_id": id.to_string(),
"type": channel::ChannelType::DM as i32, "type": channel::ChannelType::DM as i32,
"recipients": [ user.0.to_string(), target.0.to_string() ], "recipients": [ user.id, target.id ],
"active": false "active": false
}, },
None None
...@@ -153,15 +136,13 @@ enum Relationship { ...@@ -153,15 +136,13 @@ enum Relationship {
} }
fn get_relationship(a: &User, b: &User) -> Relationship { fn get_relationship(a: &User, b: &User) -> Relationship {
if a.0.to_string() == b.0.to_string() { if a.id == b.id {
return Relationship::SELF return Relationship::SELF
} }
if let Some(arr) = &b.2.relations { if let Some(arr) = &b.relations {
let id = a.0.to_string();
for entry in arr { for entry in arr {
if entry.id == id { if entry.id == a.id {
match entry.status { match entry.status {
0 => { 0 => {
return Relationship::FRIEND return Relationship::FRIEND
...@@ -190,7 +171,7 @@ fn get_relationship(a: &User, b: &User) -> Relationship { ...@@ -190,7 +171,7 @@ fn get_relationship(a: &User, b: &User) -> Relationship {
#[get("/@me/friend")] #[get("/@me/friend")]
pub fn get_friends(user: User) -> JsonValue { pub fn get_friends(user: User) -> JsonValue {
let mut results = Vec::new(); let mut results = Vec::new();
if let Some(arr) = user.2.relations { if let Some(arr) = user.relations {
for item in arr { for item in arr {
results.push( results.push(
json!({ json!({
...@@ -210,7 +191,7 @@ pub fn get_friend(user: User, target: User) -> JsonValue { ...@@ -210,7 +191,7 @@ pub fn get_friend(user: User, target: User) -> JsonValue {
let relationship = get_relationship(&user, &target); let relationship = get_relationship(&user, &target);
json!({ json!({
"id": target.0.to_string(), "id": target.id,
"status": relationship as u8 "status": relationship as u8
}) })
} }
...@@ -219,10 +200,7 @@ pub fn get_friend(user: User, target: User) -> JsonValue { ...@@ -219,10 +200,7 @@ pub fn get_friend(user: User, target: User) -> JsonValue {
#[put("/<target>/friend")] #[put("/<target>/friend")]
pub fn add_friend(user: User, target: User) -> JsonValue { pub fn add_friend(user: User, target: User) -> JsonValue {
let col = database::get_collection("users"); let col = database::get_collection("users");
let relationship = get_relationship(&user, &target); let relationship = get_relationship(&user, &target);
let User ( id, _, _ ) = user;
let User ( tid, _, _ ) = target;
match relationship { match relationship {
Relationship::FRIEND => Relationship::FRIEND =>
...@@ -238,8 +216,8 @@ pub fn add_friend(user: User, target: User) -> JsonValue { ...@@ -238,8 +216,8 @@ pub fn add_friend(user: User, target: User) -> JsonValue {
Relationship::INCOMING => { Relationship::INCOMING => {
col.update_one( col.update_one(
doc! { doc! {
"_id": id.to_string(), "_id": user.id.clone(),
"relations.id": tid.to_string() "relations.id": target.id.clone()
}, },
doc! { doc! {
"$set": { "$set": {
...@@ -251,8 +229,8 @@ pub fn add_friend(user: User, target: User) -> JsonValue { ...@@ -251,8 +229,8 @@ pub fn add_friend(user: User, target: User) -> JsonValue {
col.update_one( col.update_one(
doc! { doc! {
"_id": tid.to_string(), "_id": target.id,
"relations.id": id.to_string() "relations.id": user.id
}, },
doc! { doc! {
"$set": { "$set": {
...@@ -279,12 +257,12 @@ pub fn add_friend(user: User, target: User) -> JsonValue { ...@@ -279,12 +257,12 @@ pub fn add_friend(user: User, target: User) -> JsonValue {
Relationship::NONE => { Relationship::NONE => {
col.update_one( col.update_one(
doc! { doc! {
"_id": id.to_string() "_id": user.id.clone()
}, },
doc! { doc! {
"$push": { "$push": {
"relations": { "relations": {
"id": tid.to_string(), "id": target.id.clone(),
"status": Relationship::OUTGOING as i32 "status": Relationship::OUTGOING as i32
} }
} }
...@@ -294,12 +272,12 @@ pub fn add_friend(user: User, target: User) -> JsonValue { ...@@ -294,12 +272,12 @@ pub fn add_friend(user: User, target: User) -> JsonValue {
col.update_one( col.update_one(
doc! { doc! {
"_id": tid.to_string() "_id": target.id
}, },
doc! { doc! {
"$push": { "$push": {
"relations": { "relations": {
"id": id.to_string(), "id": user.id,
"status": Relationship::INCOMING as i32 "status": Relationship::INCOMING as i32
} }
} }
...@@ -323,10 +301,7 @@ pub fn add_friend(user: User, target: User) -> JsonValue { ...@@ -323,10 +301,7 @@ pub fn add_friend(user: User, target: User) -> JsonValue {
#[delete("/<target>/friend")] #[delete("/<target>/friend")]
pub fn remove_friend(user: User, target: User) -> JsonValue { pub fn remove_friend(user: User, target: User) -> JsonValue {
let col = database::get_collection("users"); let col = database::get_collection("users");
let relationship = get_relationship(&user, &target); let relationship = get_relationship(&user, &target);
let User ( id, _, _ ) = user;
let User ( tid, _, _ ) = target;
match relationship { match relationship {
Relationship::FRIEND | Relationship::FRIEND |
...@@ -334,12 +309,12 @@ pub fn remove_friend(user: User, target: User) -> JsonValue { ...@@ -334,12 +309,12 @@ pub fn remove_friend(user: User, target: User) -> JsonValue {
Relationship::INCOMING => { Relationship::INCOMING => {
col.update_one( col.update_one(
doc! { doc! {
"_id": id.to_string() "_id": user.id.clone()
}, },
doc! { doc! {
"$pull": { "$pull": {
"relations": { "relations": {
"id": tid.to_string() "id": target.id.clone()
} }
} }
}, },
...@@ -348,12 +323,12 @@ pub fn remove_friend(user: User, target: User) -> JsonValue { ...@@ -348,12 +323,12 @@ pub fn remove_friend(user: User, target: User) -> JsonValue {
col.update_one( col.update_one(
doc! { doc! {
"_id": tid.to_string() "_id": target.id
}, },
doc! { doc! {
"$pull": { "$pull": {
"relations": { "relations": {
"id": id.to_string() "id": user.id
} }
} }
}, },
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment