Servers: Core objects required. Includes creation. Bump version to 0.5.0.

This commit is contained in:
Paul
2021-06-01 17:09:31 +01:00
parent a4c1fee4cc
commit bff72fa6c3
23 changed files with 415 additions and 59 deletions

View File

@@ -1,2 +1,2 @@
pub mod autumn;
pub mod january;
pub mod january;

View File

@@ -1,9 +1,9 @@
mod microservice;
mod channel;
mod message;
mod microservice;
mod server;
mod user;
mod sync;
mod user;
use microservice::*;
@@ -12,5 +12,5 @@ pub use channel::*;
pub use january::*;
pub use message::*;
pub use server::*;
pub use user::*;
pub use sync::*;
pub use user::*;

View File

@@ -1,8 +1,15 @@
use crate::database::*;
use crate::notifications::events::ClientboundNotification;
use crate::util::result::{Error, Result};
use mongodb::bson::doc;
use mongodb::bson::from_document;
use mongodb::bson::to_document;
use rocket_contrib::json::JsonValue;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct MemberCompositeKey {
pub guild: String,
pub server: String,
pub user: String,
}
@@ -34,9 +41,67 @@ pub struct Server {
pub nonce: Option<String>,
pub owner: String,
pub name: String,
// pub default_permissions: u32,
pub channels: Vec<String>,
pub invites: Vec<Invite>,
pub bans: Vec<Ban>,
pub default_permissions: u32,
// pub invites: Vec<Invite>,
// pub bans: Vec<Ban>,
#[serde(skip_serializing_if = "Option::is_none")]
pub icon: Option<File>,
#[serde(skip_serializing_if = "Option::is_none")]
pub banner: Option<File>,
}
impl Server {
pub async fn get(id: &str) -> Result<Server> {
let doc = get_collection("servers")
.find_one(doc! { "_id": id }, None)
.await
.map_err(|_| Error::DatabaseError {
operation: "find_one",
with: "server",
})?
.ok_or_else(|| Error::UnknownServer)?;
from_document::<Server>(doc).map_err(|_| Error::DatabaseError {
operation: "from_document",
with: "server",
})
}
pub async fn publish(self) -> Result<()> {
get_collection("servers")
.insert_one(
to_document(&self).map_err(|_| Error::DatabaseError {
operation: "to_bson",
with: "channel",
})?,
None,
)
.await
.map_err(|_| Error::DatabaseError {
operation: "insert_one",
with: "server",
})?;
let server_id = self.id.clone();
ClientboundNotification::ServerCreate(self).publish(server_id);
Ok(())
}
pub async fn publish_update(&self, data: JsonValue) -> Result<()> {
ClientboundNotification::ServerUpdate {
id: self.id.clone(),
data,
clear: None,
}
.publish(self.id.clone());
Ok(())
}
pub async fn delete(&self) -> Result<()> {
unimplemented!()
}
}

View File

@@ -47,6 +47,10 @@ impl Ref {
self.fetch("channels").await
}
pub async fn fetch_server(&self) -> Result<Server> {
self.fetch("servers").await
}
pub async fn fetch_message(&self, channel: &Channel) -> Result<Message> {
let message: Message = self.fetch("messages").await?;
if &message.channel != channel.id() {

View File

@@ -29,6 +29,18 @@ pub async fn create_database() {
.await
.expect("Failed to create servers collection.");
db.create_collection("server_members", None)
.await
.expect("Failed to create server_members collection.");
db.create_collection("server_bans", None)
.await
.expect("Failed to create server_bans collection.");
db.create_collection("invites", None)
.await
.expect("Failed to create invites collection.");
db.create_collection("migrations", None)
.await
.expect("Failed to create migrations collection.");

View File

@@ -14,7 +14,7 @@ struct MigrationInfo {
revision: i32,
}
pub const LATEST_REVISION: i32 = 4;
pub const LATEST_REVISION: i32 = 5;
pub async fn migrate_database() {
let migrations = get_collection("migrations");
@@ -138,6 +138,25 @@ pub async fn run_migrations(revision: i32) -> i32 {
.expect("Failed to create user_settings collection.");
}
if revision <= 4 {
info!("Running migration [revision 4 / 2021-06-01]: Add more server collections.");
get_db()
.create_collection("server_members", None)
.await
.expect("Failed to create server_members collection.");
get_db()
.create_collection("server_bans", None)
.await
.expect("Failed to create server_bans collection.");
get_db()
.create_collection("invites", None)
.await
.expect("Failed to create invites collection.");
}
// Reminder to update LATEST_REVISION when adding new migrations.
LATEST_REVISION
}

View File

@@ -11,6 +11,7 @@ pub struct PermissionCalculator<'a> {
user: Option<&'a User>,
relationship: Option<&'a RelationshipStatus>,
channel: Option<&'a Channel>,
server: Option<&'a Server>,
has_mutual_connection: bool,
}
@@ -23,6 +24,7 @@ impl<'a> PermissionCalculator<'a> {
user: None,
relationship: None,
channel: None,
server: None,
has_mutual_connection: false,
}
@@ -49,6 +51,13 @@ impl<'a> PermissionCalculator<'a> {
}
}
pub fn with_server(self, server: &'a Server) -> PermissionCalculator {
PermissionCalculator {
server: Some(&server),
..self
}
}
pub fn with_mutual_connection(self) -> PermissionCalculator<'a> {
PermissionCalculator {
has_mutual_connection: true,

View File

@@ -0,0 +1,42 @@
use crate::database::*;
use crate::util::result::Result;
use super::PermissionCalculator;
use num_enum::TryFromPrimitive;
use std::ops;
#[derive(Debug, PartialEq, Eq, TryFromPrimitive, Copy, Clone)]
#[repr(u32)]
pub enum ServerPermission {
View = 1,
}
impl_op_ex!(+ |a: &ServerPermission, b: &ServerPermission| -> u32 { *a as u32 | *b as u32 });
impl_op_ex_commutative!(+ |a: &u32, b: &ServerPermission| -> u32 { *a | *b as u32 });
bitfield! {
pub struct ServerPermissions(MSB0 [u32]);
u32;
pub get_view, _: 31;
}
impl<'a> PermissionCalculator<'a> {
pub async fn calculate_server(self) -> Result<u32> {
let server = if let Some(server) = self.server {
server
} else {
unreachable!()
};
if &self.perspective.id == server.owner {
Ok(u32::MAX)
} else {
Ok(ServerPermission::View as u32)
}
}
pub async fn for_server(self) -> Result<ChannelPermissions<[u32; 1]>> {
Ok(ServerPermissions([self.calculate_server().await?]))
}
}