Add role hoisting / ranking.

Add bot creation for #8.
This commit is contained in:
Paul
2021-08-11 20:04:22 +01:00
parent e70f848f21
commit 084d71f050
18 changed files with 282 additions and 29 deletions

89
src/routes/bots/create.rs Normal file
View File

@@ -0,0 +1,89 @@
use crate::database::*;
use crate::util::result::{Error, Result};
use crate::util::variables::MAX_BOT_COUNT;
use mongodb::bson::{doc, to_document};
use regex::Regex;
use rocket::serde::json::{Json, Value};
use serde::{Deserialize, Serialize};
use ulid::Ulid;
use nanoid::nanoid;
use validator::Validate;
// ! FIXME: should be global somewhere; maybe use config(?)
// ! tip: CTRL + F, RE_USERNAME
lazy_static! {
static ref RE_USERNAME: Regex = Regex::new(r"^[a-zA-Z0-9_.]+$").unwrap();
}
#[derive(Validate, Serialize, Deserialize)]
pub struct Data {
#[validate(length(min = 2, max = 32), regex = "RE_USERNAME")]
name: String,
}
#[post("/create", data = "<info>")]
pub async fn create_bot(user: User, info: Json<Data>) -> Result<Value> {
let info = info.into_inner();
info.validate()
.map_err(|error| Error::FailedValidation { error })?;
if get_collection("bots")
.count_documents(
doc! {
"owner": &user.id
},
None,
)
.await
.map_err(|_| Error::DatabaseError {
operation: "count_documents",
with: "bots",
})? as usize >= *MAX_BOT_COUNT {
return Err(Error::ReachedMaximumBots)
}
let id = Ulid::new().to_string();
let token = nanoid!(64);
let bot = Bot {
id: id.clone(),
owner: user.id.clone(),
token,
public: false,
interactions_url: None
};
if User::is_username_taken(&info.name).await? {
return Err(Error::UsernameTaken);
}
get_collection("users")
.insert_one(
doc! {
"_id": &id,
"username": &info.name,
"bot": {
"owner": &user.id
}
},
None,
)
.await
.map_err(|_| Error::DatabaseError {
operation: "insert_one",
with: "user",
})?;
get_collection("bots")
.insert_one(
to_document(&bot).map_err(|_| Error::DatabaseError { with: "bot", operation: "to_document" })?,
None,
)
.await
.map_err(|_| Error::DatabaseError {
operation: "insert_one",
with: "user",
})?;
Ok(json!(bot))
}

9
src/routes/bots/mod.rs Normal file
View File

@@ -0,0 +1,9 @@
use rocket::Route;
mod create;
pub fn routes() -> Vec<Route> {
routes![
create::create_bot
]
}

View File

@@ -10,6 +10,7 @@ mod root;
mod servers;
mod sync;
mod users;
mod bots;
pub fn mount(rocket: Rocket<Build>) -> Rocket<Build> {
rocket
@@ -18,6 +19,7 @@ pub fn mount(rocket: Rocket<Build>) -> Rocket<Build> {
.mount("/users", users::routes())
.mount("/channels", channels::routes())
.mount("/servers", servers::routes())
.mount("/bots", bots::routes())
.mount("/invites", invites::routes())
.mount("/push", push::routes())
.mount("/sync", sync::routes())

View File

@@ -13,6 +13,8 @@ pub struct Data {
name: Option<String>,
#[validate(length(min = 1, max = 32))]
colour: Option<String>,
hoist: Option<bool>,
rank: Option<i64>,
remove: Option<RemoveRoleField>,
}
@@ -22,7 +24,7 @@ pub async fn req(user: User, target: Ref, role_id: String, data: Json<Data>) ->
data.validate()
.map_err(|error| Error::FailedValidation { error })?;
if data.name.is_none() && data.colour.is_none() && data.remove.is_none()
if data.name.is_none() && data.colour.is_none() && data.hoist.is_none() && data.rank.is_none() && data.remove.is_none()
{
return Ok(());
}
@@ -67,6 +69,16 @@ pub async fn req(user: User, target: Ref, role_id: String, data: Json<Data>) ->
set_update.insert("colour", colour);
}
if let Some(hoist) = &data.hoist {
set.insert(role_key.clone() + ".hoist", hoist);
set_update.insert("hoist", hoist);
}
if let Some(rank) = &data.rank {
set.insert(role_key.clone() + ".rank", rank);
set_update.insert("rank", rank);
}
let mut operations = doc! {};
if set.len() > 0 {
operations.insert("$set", &set);

View File

@@ -11,6 +11,7 @@ use serde::{Deserialize, Serialize};
use validator::Validate;
// ! FIXME: should be global somewhere; maybe use config(?)
// ! tip: CTRL + F, RE_USERNAME
lazy_static! {
static ref RE_USERNAME: Regex = Regex::new(r"^[a-zA-Z0-9_.]+$").unwrap();
}