From af8731ac38bca16550a724027284093f3c24dd8f Mon Sep 17 00:00:00 2001 From: Paul Makles <paulmakles@gmail.com> Date: Mon, 18 Jan 2021 13:41:48 +0000 Subject: [PATCH] Start development sprint 3. --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/database/entities/channel.rs | 36 ++-------------------------- src/database/guards/reference.rs | 24 ++++++++++++------- src/database/permissions/channel.rs | 33 +++++++++++++++++++++++++ src/database/permissions/mod.rs | 1 + src/routes/channels/fetch_channel.rs | 16 +++++++++++++ src/routes/channels/mod.rs | 6 ++++- 8 files changed, 75 insertions(+), 45 deletions(-) create mode 100644 src/database/permissions/channel.rs create mode 100644 src/routes/channels/fetch_channel.rs diff --git a/Cargo.lock b/Cargo.lock index b24b97f..335baed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2273,7 +2273,7 @@ dependencies = [ [[package]] name = "revolt" -version = "0.3.0-alpha" +version = "0.3.1" dependencies = [ "async-std", "async-tungstenite", diff --git a/Cargo.toml b/Cargo.toml index d5813bd..e8d14fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt" -version = "0.3.0-alpha" +version = "0.3.1" authors = ["Paul Makles <paulmakles@gmail.com>"] edition = "2018" diff --git a/src/database/entities/channel.rs b/src/database/entities/channel.rs index ad10efc..42bc1fc 100644 --- a/src/database/entities/channel.rs +++ b/src/database/entities/channel.rs @@ -1,39 +1,7 @@ -use crate::{ - database::get_collection, - util::result::{Error, Result}, -}; +use crate::database::*; use mongodb::bson::to_document; use serde::{Deserialize, Serialize}; - -/*#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct LastMessage { - id: String, - user_id: String, - short_content: String, -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct Channel { - #[serde(rename = "_id")] - pub id: String, - #[serde(rename = "type")] - pub channel_type: u8, - - // DM: whether the DM is active - pub active: Option<bool>, - // DM + GDM: last message in channel - pub last_message: Option<LastMessage>, - // DM + GDM: recipients for channel - pub recipients: Option<Vec<String>>, - // GDM: owner of group - pub owner: Option<String>, - // GUILD: channel parent - pub guild: Option<String>, - // GUILD + GDM: channel name - pub name: Option<String>, - // GUILD + GDM: channel description - pub description: Option<String>, -}*/ +use crate::util::result::{Error, Result}; #[derive(Serialize, Deserialize, Debug)] #[serde(tag = "type")] diff --git a/src/database/guards/reference.rs b/src/database/guards/reference.rs index bdad5ce..a71a90e 100644 --- a/src/database/guards/reference.rs +++ b/src/database/guards/reference.rs @@ -1,11 +1,11 @@ use crate::database::*; use crate::util::result::{Error, Result}; -use mongodb::bson::{doc, from_bson, Bson}; +use validator::Validate; use rocket::http::RawStr; use rocket::request::FromParam; -use serde::{Deserialize, Serialize}; -use validator::Validate; +use mongodb::bson::{doc, from_bson, Bson}; +use serde::{Deserialize, Serialize, de::DeserializeOwned}; #[derive(Validate, Serialize, Deserialize)] pub struct Ref { @@ -18,8 +18,8 @@ impl Ref { Ok(Ref { id }) } - pub async fn fetch_user(&self) -> Result<User> { - let doc = get_collection("users") + pub async fn fetch<T: DeserializeOwned>(&self, collection: &'static str) -> Result<T> { + let doc = get_collection(&collection) .find_one( doc! { "_id": &self.id @@ -29,17 +29,25 @@ impl Ref { .await .map_err(|_| Error::DatabaseError { operation: "find_one", - with: "user", + with: &collection, })? .ok_or_else(|| Error::UnknownUser)?; Ok( - from_bson(Bson::Document(doc)).map_err(|_| Error::DatabaseError { + from_bson::<T>(Bson::Document(doc)).map_err(|_| Error::DatabaseError { operation: "from_bson", - with: "user", + with: &collection, })?, ) } + + pub async fn fetch_user(&self) -> Result<User> { + self.fetch("users").await + } + + pub async fn fetch_channel(&self) -> Result<Channel> { + self.fetch("channels").await + } } impl User { diff --git a/src/database/permissions/channel.rs b/src/database/permissions/channel.rs new file mode 100644 index 0000000..cfb4ebd --- /dev/null +++ b/src/database/permissions/channel.rs @@ -0,0 +1,33 @@ +use crate::database::*; +use num_enum::TryFromPrimitive; +use std::ops; + +#[derive(Debug, PartialEq, Eq, TryFromPrimitive, Copy, Clone)] +#[repr(u32)] +pub enum ChannelPermission { + View = 1, + SendMessage = 2, +} + +bitfield! { + pub struct ChannelPermissions(MSB0 [u32]); + u32; + pub get_view, _: 31; + pub get_send_message, _: 30; +} + +impl_op_ex!(+ |a: &ChannelPermission, b: &ChannelPermission| -> u32 { *a as u32 | *b as u32 }); +impl_op_ex_commutative!(+ |a: &u32, b: &ChannelPermission| -> u32 { *a | *b as u32 }); + +pub async fn calculate(user: &User, target: &Channel) -> ChannelPermissions<[u32; 1]> { + match target { + Channel::SavedMessages { user: owner, .. } => { + if &user.id == owner { + ChannelPermissions([ ChannelPermission::View + ChannelPermission::SendMessage ]) + } else { + ChannelPermissions([ 0 ]) + } + } + _ => unreachable!() + } +} diff --git a/src/database/permissions/mod.rs b/src/database/permissions/mod.rs index 4565ef9..0240b8b 100644 --- a/src/database/permissions/mod.rs +++ b/src/database/permissions/mod.rs @@ -1,3 +1,4 @@ pub mod user; +pub mod channel; pub use user::get_relationship; diff --git a/src/routes/channels/fetch_channel.rs b/src/routes/channels/fetch_channel.rs new file mode 100644 index 0000000..4d95960 --- /dev/null +++ b/src/routes/channels/fetch_channel.rs @@ -0,0 +1,16 @@ +use crate::database::*; +use crate::util::result::{Error, Result}; + +use rocket_contrib::json::JsonValue; + +#[get("/<target>")] +pub async fn req(user: User, target: Ref) -> Result<JsonValue> { + let target = target.fetch_channel().await?; + + let perm = permissions::channel::calculate(&user, &target).await; + if !perm.get_view() { + Err(Error::LabelMe)? + } + + Ok(json!(target)) +} diff --git a/src/routes/channels/mod.rs b/src/routes/channels/mod.rs index 018a956..2137b3c 100644 --- a/src/routes/channels/mod.rs +++ b/src/routes/channels/mod.rs @@ -1,5 +1,9 @@ use rocket::Route; +mod fetch_channel; + pub fn routes() -> Vec<Route> { - routes![] + routes![ + fetch_channel::req + ] } -- GitLab