Skip to content

Commit

Permalink
Add role hoisting / ranking.
Browse files Browse the repository at this point in the history
Add bot creation for #8.
  • Loading branch information
insertish committed Aug 11, 2021
1 parent e70f848 commit 084d71f
Show file tree
Hide file tree
Showing 18 changed files with 282 additions and 29 deletions.
2 changes: 1 addition & 1 deletion set_version.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#!/bin/bash
export version=0.5.1-alpha.24
export version=0.5.2-alpha.0
echo "pub const VERSION: &str = \"${version}\";" > src/version.rs
12 changes: 12 additions & 0 deletions src/database/entities/bots.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Bot {
#[serde(rename = "_id")]
pub id: String,
pub owner: String,
pub token: String,
pub public: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub interactions_url: Option<String>,
}
2 changes: 2 additions & 0 deletions src/database/entities/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ mod microservice;
mod server;
mod sync;
mod user;
mod bots;

use microservice::*;

Expand All @@ -16,3 +17,4 @@ pub use message::*;
pub use server::*;
pub use sync::*;
pub use user::*;
pub use bots::*;
11 changes: 9 additions & 2 deletions src/database/entities/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,20 @@ pub type PermissionTuple = (
i32 // channel permission
);

fn if_false(t: &bool) -> bool {
*t == false
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Role {
pub name: String,
pub permissions: PermissionTuple,
#[serde(skip_serializing_if = "Option::is_none")]
pub colour: Option<String>
// Bri'ish API conventions
pub colour: Option<String>,
#[serde(skip_serializing_if = "if_false", default)]
pub hoist: bool,
#[serde(default)]
pub rank: i64,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
Expand Down
12 changes: 11 additions & 1 deletion src/database/entities/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,12 @@ pub enum Badges {

impl_op_ex_commutative!(+ |a: &i32, b: &Badges| -> i32 { *a | *b as i32 });

// When changing this struct, update notifications/payload.rs#80
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct BotInformation {
owner: String
}

// When changing this struct, update notifications/payload.rs#113
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct User {
#[serde(rename = "_id")]
Expand All @@ -91,6 +96,11 @@ pub struct User {
#[serde(skip_serializing_if = "Option::is_none")]
pub profile: Option<UserProfile>,

#[serde(skip_serializing_if = "Option::is_none")]
pub flags: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub bot: Option<BotInformation>,

// ? This should never be pushed to the collection.
#[serde(skip_serializing_if = "Option::is_none")]
pub relationship: Option<RelationshipStatus>,
Expand Down
55 changes: 55 additions & 0 deletions src/database/guards/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,61 @@ impl<'r> FromRequest<'r> for User {
type Error = rauth::util::Error;

async fn from_request(request: &'r Request<'_>) -> request::Outcome<Self, Self::Error> {
let header_bot_token = request
.headers()
.get("x-bot-token")
.next()
.map(|x| x.to_string());

if let Some(bot_token) = header_bot_token {
return if let Ok(result) = get_collection("bots")
.find_one(
doc! {
"token": bot_token
},
None,
)
.await
{
if let Some(doc) = result {
let id = doc.get_str("_id").unwrap();
if let Ok(result) = get_collection("users")
.find_one(
doc! {
"_id": &id
},
None,
)
.await
{
if let Some(doc) = result {
Outcome::Success(from_document(doc).unwrap())
} else {
Outcome::Failure((Status::Forbidden, rauth::util::Error::InvalidSession))
}
} else {
Outcome::Failure((
Status::InternalServerError,
rauth::util::Error::DatabaseError {
operation: "find_one",
with: "user",
},
))
}
} else {
Outcome::Failure((Status::Forbidden, rauth::util::Error::InvalidSession))
}
} else {
Outcome::Failure((
Status::InternalServerError,
rauth::util::Error::DatabaseError {
operation: "find_one",
with: "bot",
},
))
}
}

let session: Session = request.guard::<Session>().await.unwrap();

if let Ok(result) = get_collection("users")
Expand Down
4 changes: 4 additions & 0 deletions src/database/migrations/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ pub async fn create_database() {
.await
.expect("Failed to create user_settings collection.");

db.create_collection("bots", None)
.await
.expect("Failed to create bots collection.");

db.create_collection(
"pubsub",
CreateCollectionOptions::builder()
Expand Down
11 changes: 10 additions & 1 deletion src/database/migrations/scripts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ struct MigrationInfo {
revision: i32,
}

pub const LATEST_REVISION: i32 = 7;
pub const LATEST_REVISION: i32 = 8;

pub async fn migrate_database() {
let migrations = get_collection("migrations");
Expand Down Expand Up @@ -203,6 +203,15 @@ pub async fn run_migrations(revision: i32) -> i32 {
.expect("Failed to create message index.");
}

if revision <= 7 {
info!("Running migration [revision 7 / 2021-08-11]: Add message text index.");

get_db()
.create_collection("bots", None)
.await
.expect("Failed to create bots collection.");
}

// Reminder to update LATEST_REVISION when adding new migrations.
LATEST_REVISION
}
14 changes: 13 additions & 1 deletion src/notifications/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,22 @@ pub enum WebSocketError {
AlreadyAuthenticated,
}

#[derive(Deserialize, Debug)]
pub struct BotAuth {
pub token: String
}

#[derive(Deserialize, Debug)]
#[serde(untagged)]
pub enum AuthType {
User(Session),
Bot(BotAuth)
}

#[derive(Deserialize, Debug)]
#[serde(tag = "type")]
pub enum ServerboundNotification {
Authenticate(Session),
Authenticate(AuthType),
BeginTyping { channel: String },
EndTyping { channel: String },
}
Expand Down
64 changes: 43 additions & 21 deletions src/notifications/websocket.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::database::*;
use crate::notifications::events::{AuthType, BotAuth};
use crate::util::variables::WS_HOST;

use super::subscriptions;
Expand All @@ -12,8 +13,9 @@ use futures::{pin_mut, prelude::*};
use hive_pubsub::PubSub;
use log::{debug, info};
use many_to_many::ManyToMany;
use mongodb::bson::doc;
use rauth::{
auth::{Auth, Session},
auth::{Auth},
options::Options,
};
use std::collections::HashMap;
Expand Down Expand Up @@ -66,15 +68,15 @@ async fn accept(stream: TcpStream) {
}
};

let session: Arc<Mutex<Option<Session>>> = Arc::new(Mutex::new(None));
let mutex_generator = || session.clone();
let user_id: Arc<Mutex<Option<String>>> = Arc::new(Mutex::new(None));
let mutex_generator = || user_id.clone();
let fwd = rx.map(Ok).forward(write);
let incoming = read.try_for_each(async move |msg| {
let mutex = mutex_generator();
if let Message::Text(text) = msg {
if let Ok(notification) = serde_json::from_str::<ServerboundNotification>(&text) {
match notification {
ServerboundNotification::Authenticate(new_session) => {
ServerboundNotification::Authenticate(auth) => {
{
if mutex.lock().unwrap().is_some() {
send(ClientboundNotification::Error(
Expand All @@ -85,12 +87,34 @@ async fn accept(stream: TcpStream) {
}
}

if let Ok(validated_session) =
Auth::new(get_collection("accounts"), Options::new())
.verify_session(new_session)
.await
{
let id = validated_session.user_id.clone();
if let Some(id) = match auth {
AuthType::User(new_session) => {
if let Ok(validated_session) =
Auth::new(get_collection("accounts"), Options::new())
.verify_session(new_session)
.await
{
Some(validated_session.user_id.clone())
} else {
None
}
}
AuthType::Bot(BotAuth { token }) => {
if let Ok(doc) = get_collection("bots")
.find_one(
doc! { "token": token },
None
).await {
if let Some(doc) = doc {
Some(doc.get_str("_id").unwrap().to_string())
} else {
None
}
} else {
None
}
}
} {
if let Ok(user) = (Ref { id: id.clone() }).fetch_user().await {
let was_online = is_online(&id);
{
Expand All @@ -110,7 +134,7 @@ async fn accept(stream: TcpStream) {
}
}

*mutex.lock().unwrap() = Some(validated_session);
*mutex.lock().unwrap() = Some(id.clone());

if let Err(_) = subscriptions::generate_subscriptions(&user).await {
send(ClientboundNotification::Error(
Expand Down Expand Up @@ -166,8 +190,7 @@ async fn accept(stream: TcpStream) {
if mutex.lock().unwrap().is_some() {
let user = {
let mutex = mutex.lock().unwrap();
let session = mutex.as_ref().unwrap();
session.user_id.clone()
mutex.as_ref().unwrap().clone()
};

ClientboundNotification::ChannelStartTyping {
Expand All @@ -187,8 +210,7 @@ async fn accept(stream: TcpStream) {
if mutex.lock().unwrap().is_some() {
let user = {
let mutex = mutex.lock().unwrap();
let session = mutex.as_ref().unwrap();
session.user_id.clone()
mutex.as_ref().unwrap().clone()
};

ClientboundNotification::ChannelStopTyping {
Expand Down Expand Up @@ -219,13 +241,13 @@ async fn accept(stream: TcpStream) {

let mut offline = None;
{
let session = session.lock().unwrap();
if let Some(session) = session.as_ref() {
let user_id = user_id.lock().unwrap();
if let Some(user_id) = user_id.as_ref() {
let mut users = USERS.write().unwrap();
users.remove(&session.user_id, &addr);
if users.get_left(&session.user_id).is_none() {
get_hive().drop_client(&session.user_id).unwrap();
offline = Some(session.user_id.clone());
users.remove(&user_id, &addr);
if users.get_left(&user_id).is_none() {
get_hive().drop_client(&user_id).unwrap();
offline = Some(user_id.clone());
}
}
}
Expand Down

0 comments on commit 084d71f

Please sign in to comment.