Integrate voso, join_call route for channels.

This commit is contained in:
Paul
2021-03-31 11:48:52 +01:00
parent 37df18dbf7
commit 60731e1c70
9 changed files with 120 additions and 44 deletions

2
Cargo.lock generated
View File

@@ -2475,7 +2475,7 @@ dependencies = [
[[package]]
name = "revolt"
version = "0.3.3-alpha.8"
version = "0.4.0-alpha.0"
dependencies = [
"async-std",
"async-tungstenite",

View File

@@ -1,49 +1,44 @@
[package]
name = "revolt"
version = "0.3.3-alpha.8"
version = "0.4.0-alpha.0"
authors = ["Paul Makles <paulmakles@gmail.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
regex = "1"
md5 = "0.7.0"
log = "0.4.11"
ulid = "0.4.1"
rand = "0.7.3"
time = "0.2.16"
base64 = "0.13.0"
dotenv = "0.15.0"
futures = "0.3.8"
chrono = "0.4.15"
num_enum = "0.5.1"
impl_ops = "0.1.1"
web-push = "0.7.2"
many-to-many = "0.1.2"
ctrlc = { version = "3.0", features = ["termination"] }
async-std = { version = "1.8.0", features = ["tokio02", "attributes"] }
async-tungstenite = { version = "0.10.0", features = ["async-std-runtime"] }
rauth = { git = "https://gitlab.insrt.uk/insert/rauth", rev = "c52758a5087cd035b0ed9c6eacc942ba5468d2ce" }
hive_pubsub = { version = "0.4.3", features = ["mongo"] }
rocket_cors = { git = "https://github.com/insertish/rocket_cors", branch = "master" }
rocket_prometheus = { git = "https://github.com/insertish/rocket_prometheus", rev = "3d825aedb42793246c306a81fe67c5b187948983" }
rocket_contrib = { git = "https://github.com/SergioBenitez/Rocket", rev = "031948c1daaa146128d8a435be116476f2adde00" }
rocket = { git = "https://github.com/SergioBenitez/Rocket", rev = "031948c1daaa146128d8a435be116476f2adde00", default-features = false }
mongodb = { version = "1.1.1", features = ["tokio-runtime"], default-features = false }
once_cell = "1.4.1"
dotenv = "0.15.0"
ulid = "0.4.1"
bitfield = "0.13.2"
env_logger = "0.7.1"
serde_json = "1.0.57"
lazy_static = "1.4.0"
urlencoding = "1.1.1"
many-to-many = "0.1.2"
lettre = "0.10.0-alpha.1"
snafu = { version = "0.6.9" }
reqwest = { version = "0.10.8", features = ["json"] }
serde = { version = "1.0.115", features = ["derive"] }
validator = { version = "0.11", features = ["derive"] }
snafu = { version = "0.6.9" }
serde_json = "1.0.57"
bitfield = "0.13.2"
reqwest = { version = "0.10.8", features = ["json"] }
urlencoding = "1.1.1"
lazy_static = "1.4.0"
num_enum = "0.5.1"
chrono = "0.4.15"
time = "0.2.16"
rand = "0.7.3"
md5 = "0.7.0"
regex = "1"
lettre = "0.10.0-alpha.1"
env_logger = "0.7.1"
log = "0.4.11"
ctrlc = { version = "3.0", features = ["termination"] }
hive_pubsub = { version = "0.4.3", features = ["mongo"] }
async-std = { version = "1.8.0", features = ["tokio02", "attributes"] }
async-tungstenite = { version = "0.10.0", features = ["async-std-runtime"] }
rocket_cors = { git = "https://github.com/insertish/rocket_cors", branch = "master" }
mongodb = { version = "1.1.1", features = ["tokio-runtime"], default-features = false }
rauth = { git = "https://gitlab.insrt.uk/insert/rauth", rev = "c52758a5087cd035b0ed9c6eacc942ba5468d2ce" }
rocket_contrib = { git = "https://github.com/SergioBenitez/Rocket", rev = "031948c1daaa146128d8a435be116476f2adde00" }
rocket_prometheus = { git = "https://github.com/insertish/rocket_prometheus", rev = "3d825aedb42793246c306a81fe67c5b187948983" }
rocket = { git = "https://github.com/SergioBenitez/Rocket", rev = "031948c1daaa146128d8a435be116476f2adde00", default-features = false }

View File

@@ -179,7 +179,7 @@ impl Message {
builder.set_vapid_signature(signature);
builder.set_payload(ContentEncoding::AesGcm, enc.as_bytes());
let m = builder.build().unwrap();
let response = client.send(m).await.ok();
client.send(m).await.ok();
}
}

View File

@@ -12,6 +12,7 @@ pub enum ChannelPermission {
View = 1,
SendMessage = 2,
ManageMessages = 4,
VoiceCall = 8,
}
bitfield! {
@@ -20,6 +21,7 @@ bitfield! {
pub get_view, _: 31;
pub get_send_message, _: 30;
pub get_manage_messages, _: 29;
pub get_voice_call, _: 28;
}
impl_op_ex!(+ |a: &ChannelPermission, b: &ChannelPermission| -> u32 { *a as u32 | *b as u32 });
@@ -36,9 +38,7 @@ impl<'a> PermissionCalculator<'a> {
match channel {
Channel::SavedMessages { user: owner, .. } => {
if &self.perspective.id == owner {
Ok(ChannelPermission::View
+ ChannelPermission::SendMessage
+ ChannelPermission::ManageMessages)
Ok(u32::MAX)
} else {
Ok(0)
}
@@ -54,7 +54,7 @@ impl<'a> PermissionCalculator<'a> {
let perms = self.for_user(recipient).await?;
if perms.get_send_message() {
return Ok(ChannelPermission::View + ChannelPermission::SendMessage);
return Ok(ChannelPermission::View + ChannelPermission::SendMessage + ChannelPermission::VoiceCall);
}
return Ok(ChannelPermission::View as u32);
@@ -69,7 +69,7 @@ impl<'a> PermissionCalculator<'a> {
.find(|x| *x == &self.perspective.id)
.is_some()
{
Ok(ChannelPermission::View + ChannelPermission::SendMessage)
Ok(ChannelPermission::View + ChannelPermission::SendMessage + ChannelPermission::VoiceCall)
} else {
Ok(0)
}

View File

@@ -0,0 +1,65 @@
use crate::database::*;
use crate::util::result::{Error, Result};
use crate::util::variables::{USE_VOSO, VOSO_URL, VOSO_MANAGE_TOKEN};
use serde::{Serialize, Deserialize};
use rocket_contrib::json::JsonValue;
#[derive(Serialize, Deserialize)]
struct CreateUserResponse {
token: String
}
#[post("/<target>/join_call")]
pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
if !*USE_VOSO {
return Err(Error::VosoUnavailable)
}
let target = target.fetch_channel().await?;
let perm = permissions::PermissionCalculator::new(&user)
.with_channel(&target)
.for_channel()
.await?;
if !perm.get_voice_call() {
return Err(Error::MissingPermission)
}
// To join a call:
// - Check if the room exists.
// - If not, create it.
let client = reqwest::Client::new();
if let Err(error) = client
.get(&format!("{}/room/{}", *VOSO_URL, target.id()))
.header(reqwest::header::AUTHORIZATION, VOSO_MANAGE_TOKEN.to_string())
.send()
.await {
if error.status() == Some(reqwest::StatusCode::NOT_FOUND) {
if let Err(_) = client
.post(&format!("{}/room/{}", *VOSO_URL, target.id()))
.header(reqwest::header::AUTHORIZATION, VOSO_MANAGE_TOKEN.to_string())
.send()
.await {
return Err(Error::VosoUnavailable)
}
} else {
return Err(Error::VosoUnavailable)
}
}
// Then create a user for the room.
if let Ok(response) = client
.post(&format!("{}/room/{}/user/{}", *VOSO_URL, target.id(), user.id))
.header(reqwest::header::AUTHORIZATION, VOSO_MANAGE_TOKEN.to_string())
.send()
.await {
let res: CreateUserResponse = response.json()
.await
.map_err(|_| Error::InvalidOperation)?;
Ok(json!(res))
} else {
Err(Error::VosoUnavailable)
}
}

View File

@@ -5,6 +5,7 @@ mod fetch_channel;
mod group_add_member;
mod group_create;
mod group_remove_member;
mod join_call;
mod message_delete;
mod message_edit;
mod message_fetch;
@@ -24,6 +25,7 @@ pub fn routes() -> Vec<Route> {
message_delete::req,
group_create::req,
group_add_member::req,
group_remove_member::req
group_remove_member::req,
join_call::req,
]
}

View File

@@ -1,6 +1,6 @@
use crate::util::variables::{
AUTUMN_URL, DISABLE_REGISTRATION, EXTERNAL_WS_URL, HCAPTCHA_SITEKEY, INVITE_ONLY, USE_AUTUMN,
USE_EMAIL, USE_HCAPTCHA, VAPID_PUBLIC_KEY,
USE_EMAIL, USE_HCAPTCHA, VAPID_PUBLIC_KEY, USE_VOSO, VOSO_URL
};
use mongodb::bson::doc;
@@ -9,7 +9,7 @@ use rocket_contrib::json::JsonValue;
#[get("/")]
pub async fn root() -> JsonValue {
json!({
"revolt": "0.3.3-alpha.8",
"revolt": "0.4.0-alpha.0",
"features": {
"registration": !*DISABLE_REGISTRATION,
"captcha": {
@@ -21,6 +21,10 @@ pub async fn root() -> JsonValue {
"autumn": {
"enabled": *USE_AUTUMN,
"url": *AUTUMN_URL
},
"voso": {
"enabled": *USE_VOSO,
"url": *VOSO_URL
}
},
"ws": *EXTERNAL_WS_URL,

View File

@@ -69,6 +69,8 @@ pub enum Error {
InvalidOperation,
#[snafu(display("Already created an object with this nonce."))]
DuplicateNonce,
#[snafu(display("Voso is not enabled on this instance."))]
VosoUnavailable,
#[snafu(display("This request had no effect."))]
NoEffect,
}
@@ -107,6 +109,7 @@ impl<'r> Responder<'r, 'static> for Error {
Error::InvalidOperation => Status::BadRequest,
Error::TooManyIds => Status::BadRequest,
Error::DuplicateNonce => Status::Conflict,
Error::VosoUnavailable => Status::BadRequest,
Error::NoEffect => Status::Ok,
};

View File

@@ -15,8 +15,14 @@ lazy_static! {
env::var("REVOLT_APP_URL").unwrap_or_else(|_| "https://app.revolt.chat".to_string());
pub static ref EXTERNAL_WS_URL: String =
env::var("REVOLT_EXTERNAL_WS_URL").expect("Missing REVOLT_EXTERNAL_WS_URL environment variable.");
pub static ref AUTUMN_URL: String =
env::var("AUTUMN_PUBLIC_URL").unwrap_or_else(|_| "https://example.com".to_string());
pub static ref VOSO_URL: String =
env::var("VOSO_PUBLIC_URL").unwrap_or_else(|_| "https://example.com".to_string());
pub static ref VOSO_MANAGE_TOKEN: String =
env::var("VOSO_MANAGE_TOKEN").unwrap_or_else(|_| "0".to_string());
pub static ref HCAPTCHA_KEY: String =
env::var("REVOLT_HCAPTCHA_KEY").unwrap_or_else(|_| "0x0000000000000000000000000000000000000000".to_string());
pub static ref HCAPTCHA_SITEKEY: String =
@@ -39,6 +45,7 @@ lazy_static! {
pub static ref USE_HCAPTCHA: bool = env::var("REVOLT_HCAPTCHA_KEY").is_ok();
pub static ref USE_PROMETHEUS: bool = env::var("REVOLT_ENABLE_PROMETHEUS").map_or(false, |v| v == "1");
pub static ref USE_AUTUMN: bool = env::var("AUTUMN_PUBLIC_URL").is_ok();
pub static ref USE_VOSO: bool = env::var("VOSO_PUBLIC_URL").is_ok() && env::var("VOSO_MANAGE_TOKEN").is_ok();
// SMTP Settings
pub static ref SMTP_HOST: String =